Ser*_*ero 3 operator-overloading kotlin
我正在学习Kotlin - 运算符重载
我试图理解(有一个例子)运算符重载如何为函数的invoke()函数工作
预测试
fun exampleOfExtensionFunction() {
fun Int.randomize(): Int {
return Random(this.toLong()).nextInt()
}
val randomizedFive = 5.randomize()
println("$randomizedFive")
}
Run Code Online (Sandbox Code Playgroud)
印刷品:
-1157408321
fun exampleOfFunctionType() {
val printNumber: (number: Int) -> Unit
printNumber = { number ->
println("[$number = ${number.toString(16).toUpperCase()} = ${number.toString(2)}]")
}
printNumber(1023)
}
Run Code Online (Sandbox Code Playgroud)
印刷品:
[1023 = 3FF = 1111111111]
fun exampleOfOperatorOverloadingUsingExtensionFunction() {
class MyType() {
val strings: ArrayList<String> = ArrayList<String>()
override fun toString(): String {
val joiner: StringJoiner = StringJoiner(" , ", "{ ", " }")
for (string in strings) {
joiner.add("\"$string\"")
}
return joiner.toString()
}
}
operator fun MyType.contains(stringToCheck: String): Boolean {
for (stringElement in strings) {
if (stringElement == stringToCheck) return true
}
return false
}
val myType = MyType()
myType.strings.add("one")
myType.strings.add("two")
myType.strings.add("three")
println("$myType")
println("(myType.contains(\"four\")) = ${myType.contains("four")} , (\"three\" in myType) = ${"three" in myType}")
}
Run Code Online (Sandbox Code Playgroud)
印刷品:
{"one","two","three"}
(myType.contains("four"))= false,(myType中为"three")= true
测试尝试
基于以上.我尝试invoke()使用类型(Boolean, Boolean, Boolean) -> Boolean作为扩展函数的接收器类型来创建函数的运算符重载的示例invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean).然而,这没有按预期工作.
fun attemptFunctionInvokeOperatorOverloading() {
operator fun ((Boolean, Boolean, Boolean) -> Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
println("Overloaded invoke operator")
return flag1 && flag2 && flag3
}
var func1: ((Boolean, Boolean, Boolean) -> Boolean) = { flag1, flag2, flag3 ->
println("func1 body")
flag1 && flag2 && flag3
}
fun func2(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
println("func2 body")
return flag1 && flag2 && flag3
}
func1(true, true, false)
func2(true, true, true)
}
Run Code Online (Sandbox Code Playgroud)
印刷品:
func1 body
func2 body
预期:
重载的invoke运算符
重载的调用运算符
另一个问题:
这究竟是什么?(如果不是运营商超载)
operator fun ((Boolean, Boolean, Boolean) -> Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
println("Overloaded invoke operator")
return flag1 && flag2 && flag3
}
Run Code Online (Sandbox Code Playgroud)
pdp*_*dpi 10
如在另一个答案中所述,invoke是在函数对象本身上定义的,因此您无法使用扩展方法覆盖它.
我认为这里更深层次的问题是对此功能的目的略有误解.让我们来看看plus对于+操盘手.
我认为你会同意尝试定义operator fun Int.plus(b: Int): Int { /* ... */}毫无意义,因为覆盖默认+运算符是一个非常危险的事情,是吗?
但是,如果您定义复数类:
data class Complex(real: Double, img: Double)
Run Code Online (Sandbox Code Playgroud)
那么定义这个来计算复数是完全合理的:
operator fun Complex.plus(other: Complex): Complex {
val real = this.real + other.real
val img = this.img + other.img
return Complex(real, img)
}
Run Code Online (Sandbox Code Playgroud)
所以,用同样的事情invoke和():的意思()是,这是任何类似于调用一个函数为你的类型,并重写invoke的东西,已经是一个功能是自找麻烦.您想要使用它的目的是为您自己的对象提供类似函数的语法.
例如,假设你定义了一个这样的接口:
interface MyCallback {
fun call(ctx: MyContext)
}
Run Code Online (Sandbox Code Playgroud)
您使用通常的方式:
callback.call(ctx)
Run Code Online (Sandbox Code Playgroud)
但是通过invoke运算符重载的实现,您可以将其用作函数:
operator fun MyCallback.invoke(ctx: Context) = this.call(ctx)
/* Elsewhere... */
callback(ctx)
Run Code Online (Sandbox Code Playgroud)
希望澄清你如何使用invoke/()
| 归档时间: |
|
| 查看次数: |
3906 次 |
| 最近记录: |