Это можно сделать, чтобы работать как задумано - но это, вероятно, не очень хороший подход.
Непосредственной проблемой является то, что код указывает тип wordLengths
как List<Any>
. Any
верхний тип *; каждый тип является его подтипом, и поэтому вы можете безопасно получать доступ только к тем вещам, которые есть у каждого типа (например, метод toString()
).
Тем не менее, не требуется для указания типа; Вы можете оставить это на усмотрение Котлина. Если вы это сделаете, он выведет тип, который вы определили с ключевым словом object
. Этот тип является анонимным - вы не можете записать его имя - но Котлин знает об этом и может получить доступ к его полям:
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?
. Но я игнорирую обнуляемость, поскольку это не имеет отношения к этому.)