Kotlin-可变子类的扩展属性设置器

时间:2019-03-23 14:23:42

标签: kotlin properties extension-methods

假设我想拥有List的属性,然后使用MutableList的setter扩展此属性。例如,我想让列表中的最后一个元素有一个吸气剂,如果列表是可变的,我也想有一个setter。所以我想要以下内容:

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. 显式创建getter和setter:

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

    我不喜欢它,因为它没有属性语法。

1 个答案:

答案 0 :(得分:2)

只需在第二个属性中添加一个吸气剂即可调用第一个属性:

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