#kotlin #properties #extension-methods
#kotlin #свойства #расширение-методы
Вопрос:
Предположим, что я хочу иметь свойство для List
, а затем расширить это свойство с помощью средства установки для MutableList
. Например, я хочу иметь средство получения для последнего элемента в списке, а также средство установки, если список является изменяемым. Итак, я хочу следующее:
val <T> List<T>.myLast
get() = this.last()
var <T> MutableList<T>.myLast: T
set(value) {
this[this.size - 1] = value
}
Но это не компилируется. Можно ли этого достичь? Самые близкие вещи, которые я могу сделать:
-
Объявите другое свойство:
val <T> List<T>.myLast get() = this.last() var <T> MutableList<T>.myMutableLast: T get() = this.last() set(value) { this[this.size - 1] = value }
Мне это не нравится, потому что я хочу иметь то же имя.
-
Создайте средство получения и средство установки явно:
fun<T> List<T>.getMyLast() = this.last() fun<T> MutableList<T>.setMyLast(value : T) { this[this.size - 1] = value }
Мне это не нравится, потому что у него нет синтаксиса свойств.
Ответ №1:
Просто добавьте средство получения ко второму свойству, которое вызывает первое:
val <T> List<T>.myLast
get() = this.last()
var <T> MutableList<T>.myLast: T
@JvmName("someName")
get() = (this as List<T>).myLast
set(value) {
this[this.size - 1] = value
}
В этом случае вы могли бы сделать то же самое get() = this.last()
, но таким образом изменение первого определения автоматически влияет на второе.
Это будет разрешено так же, как и перегрузка метода, так что, например
val x: List<String> = mutableListOf("")
val y: MutableList<String> = mutableListOf("")
x.myLast // calls List<T>.myLast.get()
y.myLast // calls MutableList<T>.myLast.get()
Комментарии:
1. Спасибо за ответ. Вы имеете в виду, что я сначала объявляю
val <T> List<T>.myLast get() = this.last()
, а затем то, что вы написали? Тогда я получаю"Platform declaration clash: The following declarations have the same JVM signature ...: fun List<T>.<get-myLast>(): ... fun MutableList<T>.<get-myLast>(): ..."
.2. Ах да, я упустил из виду, что это произойдет в данном конкретном случае, потому что
List
иMutableList
сопоставлены с одним и тем же типом. Итак, вам нужна@JvmName
аннотация к одному из средств получения.