10

I was experimenting with setting uninitialized values and was trying to get the following to work. This is mostly a curiosity in the power (and limitations) of reified generics.

I was attempting to provide default values for optional parameters of data classes.

inline fun <reified T> uninitialized(): T = when (T::class) {
  Long::class -> -1L // Type mismatch. Required: T  Found: Long
  String::class -> "" // Type mismatch. Required: T  Found: String
  // and so on...
  else -> throw UnsupportedOperationException("No uninitialized value defined for " + T::class)
}

data class Thing(
    var id: Long = uninitialized(),
    var name: String = uninitialized() // and so on...
)

When when includes is Type clauses, Kotlin has smart casting. In this example, smart casting isn't kicking in so this will not compile.

Any ideas to accomplish something similar?

4

1 回答 1

8

在您用于is检查其类型或将其与null. 在您的示例中,没有您检查类型的特定对象,也没有可以应用智能转换的对象。

但是,您可以将手动转换应用于T,这将按预期工作。这是您的示例函数的工作版本,已更新以处理将在 1.1 中修复的 Kotlin 反射库的特性:

inline fun <reified T : Any> uninitialized(): T = when (T::class.java) {
  Long::class.javaPrimitiveType, Long::class.javaObjectType -> -1L as T      
  String::class.java -> "" as T
  // and so on...
  else -> throw UnsupportedOperationException("No uninitialized value defined for " + T::class)
}

data class Thing(
    var id: Long = uninitialized(),
    var name: String = uninitialized() // and so on...
)

fun main(args: Array<String>) {
    val t = Thing()
    println(t.id)
}
于 2016-08-09T19:34:13.807 回答