为什么委托 class 方法的 getValue 和 setValue 需要用 operator 关键字标记?
Why do delegate class methods getValue and setValue need to marked with operator keyword?
这是 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.")
}
}
我不确定我是否正确理解了您的问题,但我们添加了 operator
以将函数标记为不仅仅是常规函数,而是指定用于提供某些特定功能的函数。这并不局限于委托属性——它对所有操作符都是一样的。
我认为标记为运算符至少有两个好处。首先,reader 明确表示该函数可以与某些语言特性一起使用。其次,它有助于避免我们打算提供一些操作员但我们犯了错误的情况,例如在参数类型中,所以它被默默地忽略了。 operator
立即告诉我们函数签名是否正确。
这是因为委托属性是 defined by convention。这意味着:
[its] semantics are defined through syntactic expansion of one syntax form into another syntax form.
可以看到委托的扩展属性 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)
}
按照惯例定义的语法特征之一是(从第一个 link 开始):
All call expressions that are produced by expansion are only allowed to use operator functions.
还有:
This expansion of a particular syntax form to a different piece of code is usually defined in the terms of operator functions.
只是为了给您提供更多示例,第一个 link 显示了更多按约定定义的语法示例。下面是与它们相关的相应运算符函数:
Syntax defined by convention
Related operator functions
Arithmetic and comparison operators
plus
, compareTo
etc
invoke
convention
invoke
Operator-form assignments
plusAssign
, minusAssign
etc
For-loop statements
iterator
, hasNext
, next
Delegated properties
setValue
, getValue
Destructuring declarations
component1
, component2
etc
请注意,您需要在所有这些函数上加上单词 operator
才能使相应的语法起作用。换句话说,“operator
”表示该函数可以在约定定义的语法中使用。
这是 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.")
}
}
我不确定我是否正确理解了您的问题,但我们添加了 operator
以将函数标记为不仅仅是常规函数,而是指定用于提供某些特定功能的函数。这并不局限于委托属性——它对所有操作符都是一样的。
我认为标记为运算符至少有两个好处。首先,reader 明确表示该函数可以与某些语言特性一起使用。其次,它有助于避免我们打算提供一些操作员但我们犯了错误的情况,例如在参数类型中,所以它被默默地忽略了。 operator
立即告诉我们函数签名是否正确。
这是因为委托属性是 defined by convention。这意味着:
[its] semantics are defined through syntactic expansion of one syntax form into another syntax form.
可以看到委托的扩展属性 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)
}
按照惯例定义的语法特征之一是(从第一个 link 开始):
All call expressions that are produced by expansion are only allowed to use operator functions.
还有:
This expansion of a particular syntax form to a different piece of code is usually defined in the terms of operator functions.
只是为了给您提供更多示例,第一个 link 显示了更多按约定定义的语法示例。下面是与它们相关的相应运算符函数:
Syntax defined by convention | Related operator functions |
---|---|
Arithmetic and comparison operators | plus , compareTo etc |
invoke convention |
invoke |
Operator-form assignments | plusAssign , minusAssign etc |
For-loop statements | iterator , hasNext , next |
Delegated properties | setValue , getValue |
Destructuring declarations | component1 , component2 etc |
请注意,您需要在所有这些函数上加上单词 operator
才能使相应的语法起作用。换句话说,“operator
”表示该函数可以在约定定义的语法中使用。