свойство доступа kotlin анонимного объекта - PullRequest
0 голосов
/ 07 мая 2019

Как получить доступ к свойству 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) }
    }

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

Вы явно объявляете 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 сама).См. Выражения объектов :

Обратите внимание, что анонимные объекты могут использоваться как типы только в локальных и частных объявлениях.Если вы используете анонимный объект в качестве возвращаемого типа публичной функции или типа открытого свойства, фактический тип этой функции или свойства будет объявленным супертипом анонимного объекта или Any, если вы не объявилилюбой супертип.Члены, добавленные в анонимный объект, не будут доступны.

1 голос
/ 07 мая 2019

Это можно сделать, чтобы работать как задумано - но это, вероятно, не очень хороший подход.

Непосредственной проблемой является то, что код указывает тип 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?. Но я игнорирую обнуляемость, поскольку это не имеет отношения к этому.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...