如何访问匿名对象的对象的属性word
fun main(args: Array<String>) {
val sentence = "this is a nice sentence"
val wordLengths: List<Any> = sentence.split(' ').map {
object {
val length = it.length
val word = it
}
}
wordLengths.forEach { it:Any -> println(it) }
}
答案 0 :(得分:2)
您明确声明wordLengths
为List<Any>
,并且Any
没有word
或length
属性。您应该让Kotlin从map
推断类型。
fun main() {
val sentence = "This is a nice sentence"
val wordLengths = sentence.split(' ').map {
object {
val word = it
val length = it.length
}
}
wordLengths.forEach {
println("[${it.length}] ${it.word}")
}
}
如果您打算在方法之外使用此对象,则应创建必要的类或使用现有的类(例如Pair
或String
本身)。参见Object expressions:
请注意,匿名对象只能在本地和私有声明中用作类型。如果您将匿名对象用作公共函数的返回类型或公共属性的类型,则该函数或属性的实际类型将是该匿名对象的声明超类型,或者如果没有,则为
Any
声明任何超类型。添加到匿名对象中的成员将不可访问。
答案 1 :(得分:1)
可以使其按预期工作,但这可能不是一个好方法。
当前的问题是代码将wordLengths
的类型指定为List<Any>
。 Any
是顶部类型*;每个类型都是它的子类型,因此您只能安全地访问每个类型具有的内容(例如toString()
方法)。
但是,您不需要指定类型;您可以将其留给Kotlin的类型推断。如果这样做,它将推断您使用object
关键字定义的类型。该类型是匿名的-您不能写下它的名称-但Kotlin知道它,并且可以访问其字段:
fun main() {
val sentence = "this is a nice sentence"
val wordLengths = sentence.split(' ').map {
object {
val length = it.length
val word = it
}
}
wordLengths.forEach{ println(it.word) }
}
也就是说,它有点笨拙和脆弱。您最好为类型定义一个类。实际上,总的来说较短:
fun main2() {
val sentence = "this is a nice sentence"
class Word(val length: Int, val word: String)
val wordLengths = sentence.split(' ').map{ Word(it.length, it) }
wordLengths.forEach { println(it.word) }
}
(实际上,您可能想在其他地方使用新类,然后将其移到方法之外。但是Kotlin允许您定义本地类。)
———
(*实际上,顶部类型是可空的Any:Any?
。但是我忽略了可空性,因为它与此无关。)