首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用映射的数组的自定义属性委托

使用映射的数组的自定义属性委托
EN

Stack Overflow用户
提问于 2018-11-20 09:50:40
回答 1查看 155关注 0票数 1

假设我正在尝试实现实例,而委派的属性之一是数组:

代码语言:javascript
复制
class Foo private constructor(map: Map<String, Any?>) {
    constructor(value: Array<Byte>) : this(mapOf(Foo::value.name to value))

    val value: Array<Byte> by map
}

object PropertyDelegationTest {
    @JvmStatic
    fun main(vararg args: String) {
        val foo = Foo(arrayOf(42.toByte(), 127.toByte()))
        println(foo.value[0]) // 42
        println(foo.value[1]) // 127
    }
}

上面的编译非常好,并按预期的方式工作。

现在考虑通过实现自定义Map.getValue(thisRef: Any?, property: KProperty<*>)扩展方法(覆盖默认扩展)来增强我的属性委托机制:

代码语言:javascript
复制
import kotlin.reflect.KProperty
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.full.starProjectedType
import kotlin.reflect.jvm.jvmName

// ...

operator fun <V, V1 : V> Map<in String, V>.getValue(thisRef: Any?, property: KProperty<*>): V1 {
    val value = this[property.name]
                ?: throw NoSuchElementException("Key ${property.name} is missing in the map.")
    val clazz = (value as Any)::class
    @Suppress("UNCHECKED_CAST")
    return when {
        clazz.starProjectedType.isSubtypeOf(property.returnType) -> value as V1
        else -> throw ClassCastException("${clazz.starProjectedType} (${clazz.jvmName}) cannot be cast to ${property.returnType}")
    }
}

这在运行时失败:

代码语言:javascript
复制
Exception in thread "main" java.lang.ClassCastException: kotlin.Array<*> ([Ljava.lang.Byte;) cannot be cast to kotlin.Array<kotlin.Byte>
    at com.example.PropertyDelegationTestKt.getValue(PropertyDelegationTest.kt:30)
    at com.example.Foo.getValue(PropertyDelegationTest.kt)
    at com.example.PropertyDelegationTest.main(PropertyDelegationTest.kt:18)

尽管已知有效的JVM类型([Ljava.lang.Byte;),但特定于Kotlin的值的运行时类型是Array<*>,而Array<Byte>是必需的。一致地,clazz.typeParameters[0].upperBounds[0]的计算结果为kotlin.Any?,而不是 kotlin.Byte?

如何实现我的自定义类型检查,它也将正确地工作在数组上?Kotlin版本为1.2.71。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-21 08:06:34

您可以删除显式类型检查,而是对V1执行安全的强制转换,如果转换失败,则抛出异常。

代码语言:javascript
复制
return value as? V1 ?: throw ClassCastException(... 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53390285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档