This can be made to work as intended — but it's probably not a good approach.
The immediate issue is that the code specifies the type of wordLengths
as List<Any>
. Any
is the top type*; every type is a subtype of it, and so you can only safely access things that every type has (such as the toString()
method).
However, you don't need to specify the type; you can leave that to Kotlin's type inference. If you do, it infers the type that you've defined with the object
keyword. That type is anonymous — you can't write down its name — but Kotlin knows about it, and can access its fields:
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) }
}
That said, it's a bit awkward and fragile. You'd be better off defining a class for the type. In fact, that's shorter overall:
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) }
}
(In practice, you'd probably want to use the new class elsewhere, and move it outside the method. But Kotlin lets you define local classes if you need to.)
———
(* Actually, the top type is nullable Any: Any?
. But I'm ignoring nullability as it's not relevant to this.)