假设我有一个需要一个类类型和布尔值的委托类。如果此委托所使用的属性的类型为可为空,则我具有特定的功能。为了简单起见,假设根据Boolean参数,它会为null引发错误。
class Sample<T: Any> (val type: KClass<T>,
val allowNulls: Boolean){
private var value: T?
operator fun getValue(thisRef: Any, property: KProperty<*>): T? {
return if (allowNulls)
value
else
value?: throw Exception("Value is null!")
}
operator fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
this.value = value
}
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个简化函数,以轻松生成此类的实例,该实例自动确定类型是否应为可为空。同样,这对于对于可为空的属性表现不同的委托很有用。例如,这将用于允许不同的行为,具体取决于委派的属性是否可为空:
val nullableString by sample<String?>()
val nonnullString by sample<String>()
val nullableString2: String? by sample()
val nonnullString2: String by sample()
Run Code Online (Sandbox Code Playgroud)
我如何确定该类型化是否可为空?我看不到访问此信息的方法:
inline fun <reified T: Any> sample(): Sample<T>{
return Sample(T::class, /** T is nullable */)
}
Run Code Online (Sandbox Code Playgroud)
如果T是经过修饰的泛型类型参数,则可以通过简单的方法(尽管乍一看并不明显)来查找它是否可为空:
if (null is T) {
// T is nullable
}
Run Code Online (Sandbox Code Playgroud)
但是在您的示例中T具有Any上限,因此表达式将始终为false。
有一个非常简单的答案!但首先:
请记住,Kotlin中的顶级类型是Any?(可为空)。不可为空的Any是一个子类型,所有不可为空的类型都从该子类型派生。因此,如果类型不是的子类型,则该类型可以为空Any。
因此,您的泛型<reified T: Any>已经限制为不可为null的类型,并且您的函数只能使用false!
但是,如果您放宽该限制,则测试将变得公正null is T—毕竟,如果类型包含null为值,则该类型可以为空:
inline fun <reified T: Any?> sample(): Sample<T> {
return Sample(T::class, null is T)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45 次 |
| 最近记录: |