Kotlin - установщик свойства расширения для изменяемого подкласса - PullRequest
1 голос
/ 23 марта 2019

Предположим, что я хочу иметь свойство для List, а затем расширить это свойство с помощью setter для MutableList. Например, я хочу иметь метод получения последнего элемента в списке, а также метод установки, если список изменчив. Поэтому я хочу следующее:

val <T> List<T>.myLast
    get() = this.last()

var <T> MutableList<T>.myLast: T
    set(value) {
        this[this.size - 1] = value
    }

Но это не компилируется. Можно ли этого достичь? Ближайшие вещи, которые я могу сделать:

  1. Объявите другое свойство:

    val <T> List<T>.myLast
        get() = this.last()
    
    var <T> MutableList<T>.myMutableLast: T
        get() = this.last()
        set(value) {
            this[this.size - 1] = value
        }
    

    Мне это не нравится, потому что я хочу иметь то же имя.

  2. Создайте метод получения и установки явно:

    fun<T> List<T>.getMyLast() = this.last()
    
    fun<T> MutableList<T>.setMyLast(value : T) {
        this[this.size - 1] = value
    }
    

    Мне это не нравится, потому что у него нет синтаксиса свойств.

1 Ответ

2 голосов
/ 23 марта 2019

Просто добавьте геттер ко второму свойству, которое вызывает первое:

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()
...