Kotlin中访问Map值对象的name字段失败问题排查与解决
问题分析与解决
报错原因
你创建的mapOf("1" to A(), "2" to B())中,Kotlin编译器会自动推断Map的值类型为Any——因为A和B没有共同的父类(除了默认的Any)。而Any类并没有定义name属性,所以编译器无法识别v.name这个引用,直接报错。
解决方法
有两种常用的合理方案:
方案1:定义共同接口/抽象类(推荐)
给A和B定义一个包含name属性的共同接口,让两个类实现该接口,这样Map的值类型会被推断为这个接口类型,就能直接访问name:
interface HasName { val name: String } class A : HasName { override val name = "A" } class B : HasName { override val name = "B" } // 此时Map的值类型为HasName var m = mapOf("1" to A(), "2" to B()) for ((k, v) in m) { println(v.name) // 正常编译运行 }
方案2:类型检查与智能转换
如果不想修改原有类的结构,可以在遍历的时候通过类型检查来识别实例类型,Kotlin会自动进行智能转换,之后就能访问对应类的name属性:
for ((k, v) in m) { when (v) { is A -> println(v.name) is B -> println(v.name) } }
这种方式适合临时场景,但如果后续新增类似的类,需要手动更新when分支,扩展性不如方案1。
内容的提问来源于stack exchange,提问作者Radu Călin
相关产品推荐
相关产品推荐

