【发布时间】:2021-10-23 13:41:23
【问题描述】:
我期待看到输出
black
white
下面的代码
package delegate
import kotlinx.coroutines.runBlocking
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
open class Color(private val name: String) {
override fun toString(): String {
return name
}
}
class Black : Color("black")
class White : Color("white")
class ColorCollection {
private val black = Black()
private val white = White()
val list = listOf(black, white)
}
class Palette {
val black: Black by ColorDelegate()
val white: White by ColorDelegate()
val colorCollection = ColorCollection()
}
class ColorDelegate<T> : ReadOnlyProperty<Palette, T> {
override fun getValue(thisRef: Palette, property: KProperty<*>): T {
return thisRef.colorCollection.list.mapNotNull { it as? T }.first()
}
}
fun main() = runBlocking {
val palette = Palette()
println(palette.black)
println(palette.white)
}
但是,我只得到黑色输出,然后是Exception in thread "main" java.lang.ClassCastException: delegate.Black cannot be cast to delegate.White。
我发现使用这一行thisRef.colorCollection.list.mapNotNull { it as? T },我希望它只返回列表中可以安全地转换为泛型类型的值,否则返回null。例如,在 Palette 中访问黑色委托属性时,我应该只看到 thisRef.colorCollection.list.mapNotNull { it as? T } 返回的 1 个黑色元素,它实际上返回了两个(黑色和白色)。无论 T 是什么,it as? T 总是以某种方式工作。我还尝试在该行放置一个断点,尝试将“abcdef”设置为 T?,它也可以工作,我希望看到 String 无法转换为 Black 的转换异常......
这是一个错误吗...?
【问题讨论】: