T 和 T 和有什么不一样?在科特林?

Fre*_*uvn 7 kotlin

有什么区别:

fun <T, R> List<T>.map1(transform: (T) -> R): List<R> {
    return this.map(transform)
}
Run Code Online (Sandbox Code Playgroud)

fun <T, R> List<T>.map2(transform: (T?) -> R): List<R> {
    return this.map(transform)
}
Run Code Online (Sandbox Code Playgroud)

fun <T, R> List<T?>.map3(transform: (T?) -> R): List<R> {
    return this.map(transform)
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中,null被接受了上述所有3个变换功能,所以:有什么区别TT?

Sam*_*Sam 7

在您的示例中,TT?是等效的,但在其他情况下?确实有所不同。

当你声明一个类型参数时<T>,它没有任何限制。它与 write 相同<T: Any?>,这意味着T将允许Any?. 向?它添加 a将使其可以为空,但Any?已经可以为空,因此?不会改变任何内容。这意味着无界类型允许的类型T集与 允许的类型集相同T?

但是,一旦您对T可能发生的事情施加限制,事情就会发生变化。例如,在下面的函数中,我们声明了一个类型参数<T: Any>,将其限制为不再可以为空。

fun <T: Any> myFunction(item: T) // item can't be null
Run Code Online (Sandbox Code Playgroud)

这意味着我不能传递nullmyFunction. 我只能叫一个函数null的参数,如果我改变参数是的类型T?

fun <T: Any> myFunction(item: T?) // item can be null
Run Code Online (Sandbox Code Playgroud)

请注意,?只是注释现有的类型参数。用 a声明类型参数?没有任何意义,也不会编译。例如,fun <T?> myFunction(item: T)不是有效的 Kotlin 代码。

  • 两者都不; `T?` 是 `T` 的超类型,因为它可以保存任何类型 `T` 的值,也可以保存 null。 (2认同)
  • 一个有趣的旁注:从技术上讲,超类型不必允许比基类型更多的类型,它只需要允许至少同样多的类型。当“T”无界时,“T?”仍被视为“T”的超类型,即使它允许完全相同的类型集。Kotlin 编译器仍然应用普通的超类型规则,因此,如果我有一个“T?”类型的值,则不允许将其分配给“T”类型的变量。 (2认同)