这两个Kotlin扩张函数有什么不同吗?
fun Any?.f(o: Any?) = 100
fun <T> T.g(o: T) = 100
是否有可能以这样一种方式重写g
,使其参数类型和接收器类型强制相同?
也就是说,10.g(5)
和"x".g("y")
可以,但10.g("y")
不能编译.
编辑: 给出this个,我想我第二个问题的答案是否定的,没有一个增加了额外的论点.
这两个Kotlin扩张函数有什么不同吗?
fun Any?.f(o: Any?) = 100
fun <T> T.g(o: T) = 100
是否有可能以这样一种方式重写g
,使其参数类型和接收器类型强制相同?
也就是说,10.g(5)
和"x".g("y")
可以,但10.g("y")
不能编译.
编辑: 给出this个,我想我第二个问题的答案是否定的,没有一个增加了额外的论点.
我认为在 compose 本答案(Kotlin 1.7.20)时,官方还不可能做到这一点.
然而,在内部,Kotlin编译器支持这种情况,它允许更改默认行为并使用精确的类型参数.这由内部的@Exact
注释控制,并且在整个Kotlin stdlib中的许多地方使用.
通过一些黑客攻击,我们可以在自己的代码中启用此行为:
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
fun <T> @kotlin.internal.Exact T.g(o: @kotlin.internal.Exact T) = 100
当然,这纯粹是一次黑客攻击,它可能会在future 的Kotlin版本中停止工作.
Update个
回答你的第一个问题,即使用Any
和T
是否有区别.如果类型参数不仅被使用,而且还被进一步传递,则泛型函数最有意义.例如,如果函数返回T
或它接收到一个使用T
的对象:
fun main() {
var result = 5.g(7)
}
fun <T> T.g(o: T): T = if (...) this else o
在本例中,result
的类型为Int
.如果我们使用Any
而不是T
,那么result
也必须是Any
.