代码之家  ›  专栏  ›  技术社区  ›  Alexander Suraphel

为什么委托类方法getValue和setValue需要用运算符关键字标记?

  •  0
  • Alexander Suraphel  · 技术社区  · 3 年前

    以下是中的一个示例 Delegated properties 文档

    import kotlin.reflect.KProperty
    
    class Delegate {
        operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
            return "$thisRef, thank you for delegating '${property.name}' to me!"
        }
    
        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
            println("$value has been assigned to '${property.name}' in $thisRef.")
        }
    }
    
    2 回复  |  直到 3 年前
        1
  •  4
  •   Sweeper    3 年前

    这是因为委派的属性 defined by convention 。这意味着:

    其语义是通过将一种语法形式扩展到另一种语法格式来定义的。

    您可以看到委派属性的扩展 further down the documentation page :

    class C {
        var prop: Type by MyDelegate()
    }
    
    // this code is generated by the compiler instead:
    class C {
        private val prop$delegate = MyDelegate()
        var prop: Type
            get() = prop$delegate.getValue(this, this::prop)
            set(value: Type) = prop$delegate.setValue(this, this::prop, value)
    }
    

    按照惯例定义的语法的一个特征是(从第一个环节来看):

    所有通过扩展生成的调用表达式都只允许使用运算符函数。

    以及:

    将特定语法形式扩展到不同的代码段通常是根据运算符函数定义的。

    为了给您更多的示例,第一个链接显示了更多由约定定义的语法示例。以下是与它们相关的相应操作员功能:

    由约定定义的语法 相关操作员功能
    算术运算符和比较运算符 plus , compareTo
    invoke 习俗 援引
    操作员表单分配 plusAssign , minusAssign
    For循环语句 iterator , hasNext , next
    委派的属性 setValue , getValue
    正在破坏声明 component1 , component2

    注意,你需要把这个词 operator 对所有这些函数执行相应的语法。换句话说,“ 操作人员 ”表示此函数可以在约定定义的语法中使用。

        2
  •  1
  •   broot    3 年前

    我不确定我是否正确理解你的问题,但我们补充 operator 将函数标记为不仅是常规函数,而且是指定用于提供某些特定功能的函数。这并不仅限于委派的属性,对于所有操作符都是一样的。

    我认为标记为操作员至少有两个好处。首先,向读者明确地表明,该函数可以与某些语言特征一起使用。其次,它有助于避免我们打算提供一些运算符,但我们犯了一个错误,例如在参数类型中,所以它被默默地忽略了。 操作人员 立即告诉我们函数签名是否正确。