Насколько я знаю, тип 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() = this::class.java.simpleName
У вас будет несколько ошибок в этой строке:
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}?
На самом деле их нет. Выражение присваивания для функций — это просто сокращение. Так что еще короче: val Any.classTag get() = this::class.java.simpleName. Тогда вы даже можете пропустить возвращаемый тип.
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
Ваша проблема может быть решена путем предоставления метода получения вашей переменной, например:
val Any.classTag: String get() { return this::class.java.simpleName }