Как объявить расширение val для любого типа в Котлине

Насколько я знаю, тип Any в Kotlin похож на Object в java, который по умолчанию реализуется любым классом, который мы объявляем. Я хочу расширить имя класса на новое valclassTag. Таким образом,

Когда я расширяю функцию, она работает нормально,

fun Any.getClassTag(): String { return this::class.java.simpleName }

Но я обнаружил ошибку компилятора в случае, когда я расширяю тип val.

val Any.classTag: String { return this::class.java.simpleName }

Function declaration must have a name

Как с этим быть?

Ваша проблема может быть решена путем предоставления метода получения вашей переменной, например: val Any.classTag: String get() { return this::class.java.simpleName }

Jeel Vankhede 25.06.2019 08:43
2
1
1 221
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы создаете свойство расширения, как будто это функция. Правильный способ создать свойство расширения — определить методы получения и установки свойств. вот что вы должны были сделать:

val Any.classTag: String
    get() = this::class.java.simpleName

Пример игровой площадки Kotlin

Ответ принят как подходящий

У вас будет несколько ошибок в этой строке:

Error:(1, 0) Extension property must have accessors or be abstract
Error:(1, 23) Property getter or setter expected
Error:(1, 24) Expecting a top level declaration
Error:(1, 25) Function declaration must have a name
Error:(1, 34) 'this' is not defined in this context

Это потому, что вы неправильно объявили средства доступа:

val Any.classTag: String get() { return this::class.java.simpleName }

Вам нужно только добавить аксессор get() непосредственно перед вашим блоком.

Итак, в чем разница между val Any.classTag: String get() = this::class.java.simpleName и val Any.classTag: String get() { return this::class.java.simpleName}?

Sazzad Hissain Khan 25.06.2019 09:04

На самом деле их нет. Выражение присваивания для функций — это просто сокращение. Так что еще короче: val Any.classTag get() = this::class.java.simpleName. Тогда вы даже можете пропустить возвращаемый тип.

tynn 25.06.2019 09:12

According to Kotlin Docs, Initializers are not allowed for extension properties.

Таким образом, единственный способ предоставить значение свойству расширения — это явно указать геттеры/сеттеры.

В вашем случае это должно быть, как показано ниже:

val Any.classTag: String 
    get() { 
        return this::class.java.simpleName
    }

Проверьте этоСвойства расширения

Note that, since extensions do not actually insert members into classes, there's no efficient way for an extension property to have a backing field. This is why initializers are not allowed for extension properties. Their behavior can only be defined by explicitly providing getters/setters.

val Any.classTag: String  get() = this::class.java.simpleName

Другие вопросы по теме