为什么科特林不能覆盖的List <*>操作方法?(Why Kotlin can not

2019-09-29 22:09发布

这里是我的功能:

operator  infix fun  List<Teacher>.get(int: Int): Teacher {
    var t = Teacher()
    t.name = "asd"
    return t ;
}

我的用法:

b[0].teachers[1].name

提示:b为具有列表<教师>属性的对象

和错误Empty list doesn't contain element at index 1.

为什么这个重写操作功能不起作用?

Answer 1:

在科特林,你不能用阴影延伸的成员函数。 成员总是胜在电话解决。 所以,你根本不能称之为一个签名相同于一个成员函数,即存在于被宣布或推断表达类型的扩展名。

class C {
    fun foo() { println("member") }
}

fun C.foo() { println("extension") }

C().foo() // prints "member"

在你的情况下,成员函数是abstract operator fun get(index: Int): E定义kotlin.collections.List

请参阅语言参考: 扩展是静态解析



Answer 2:

作为voddan在评论中提到,你不能掩盖与扩展的方法。 然而,有一种方法来解决这个问题的一些多态性。 我不认为我会建议你的情况做这个,但我想它展示了一个很酷的科特林功能。

如果b[0]返回类型的对象B ,你可以在该类做到这一点:

data class B(private val _teachers: List<Teacher> = emptyList()) {
    private class Teachers(private val list: List<Teacher>) : List<Teacher> by list {
        override operator fun get(int: Int): Teacher {
            var t = Teacher() 
            t.name = "asd"
            return t ;
        }
    }

    val teachers: List<Teacher> = Teachers(_teachers)
}

fun main(args: Array<String>) {
    println(B().teachers[0].name) // Prints "asd"
}

当我重写get -function它会影响大家使用B类,不只是在那里你将导入的扩展功能。

请注意,我委托的其他所有方法,调用Teachers通过对基础列表-class。



文章来源: Why Kotlin can not override List<*> operator method?
标签: kotlin