可空操作符在泛型类中是否有效?

gre*_*man 2 generics nullable kotlin

Kotlin有很多功能(?.和!!.)处理可空类型.但是这个只是让我感到震惊 - 如果你不知道你是在处理可空或不可空类型呢?如果你有泛型类MyClass<T>,那么你只需要一些类型就可以了T.

Kotlin是否允许将"可空"运算符应用于泛型类型(T此处),类型是否可以在类(如T?)中变为可空,以及如果类将使用可空类型实例化,如果类似MyClass<String?>.它会**std::string在MyClass类型中导致可为空的可空(如指向C++中的指针 - )类型吗?

Kir*_*man 5

我刚刚在Web Demo中尝试过它.

class MyClass<T>(val x: T) {
  fun foo() {
    println(x.toString())
  }

  fun fooSave() {
    println(x?.toString())
  }

}

fun main(args: Array<String>) {
  MyClass<String?>(null).fooSave()
  MyClass<String?>(null).foo()
}
Run Code Online (Sandbox Code Playgroud)

看起来你总是可以应用null-safe操作符?.,即使类型不一定是可空的.

在另一方面,你可以在泛型类型参数绑定T到一个可空类型,在我的情况String?,这在事实上,如果你通过将产生一个NullPointerException异常null.

编辑:自从提出问题以来,没有上限的泛型类型的语义已经改变.T现在解释为T : Any?.但是上面的代码不再崩溃了.原因是调用x.toString()将调用Any?.toString()正确处理nulls 的扩展函数.

如果我们更改代码如下

class MyClass<T : Any>(val x: T) {
  fun foo() {
    println(x.toString())
  }

  fun fooSave() {
    println(x?.toString())
  }

}

fun main(args: Array<String>) {
  MyClass<String?>(null).fooSave()
  MyClass<String?>(null).foo()
}
Run Code Online (Sandbox Code Playgroud)

现在甚至不进行编译,因为我们不能实例化T : Any用String?.该呼叫x?.toString()还标有警告,表示不需要安全呼叫.

  • 只是输入`T`被解释为`T:Any?`所以没有"只输入`T`",因为编译器会将其视为可为空.您可以使用`T:Any`来定义不可为空的不同上限. (2认同)