可空运算符在泛型 class 中有效吗?

Are nullable operators valid within generic class?

Kotlin 具有处理可空类型的漂亮功能(?.!!.)。但这只是抚摸我——如果您不知道您正在处理可空类型还是不可空类型怎么办?如果你有泛型 class MyClass<T> 怎么办,那么你只有一些类型 T 就是这样。

Kotlin 是否允许将 "nullable" 运算符应用于泛型类型(此处为 T),是否可以使类型可为空 inside class(如 T?),如果 class 将被实例化为可空类型——如 MyClass<String?> 会怎样?它会导致 MyClass 类型内的可空类型(如 C++ 中指向指针的指针——**std::string)类型吗?

我刚刚在 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()
}

似乎您始终可以应用 null 安全运算符 ?.,即使类型不一定可为 null。

另一方面,您可以将泛型类型参数 T 绑定到可为 null 的类型,在我的例子中 String? 如果您这样做,实际上会产生 NullPointerException通过 null.

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

的扩展函数 Any?.toString()

如果我们把代码改成下面这样

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()
}

它现在甚至无法编译,因为我们无法用 String? 实例化 T : Any。调用 x?.toString() 也带有警告标记,表明安全调用是不必要的。