gpt4 book ai didi

operator-overloading - Kotlin - 函数的调用运算符重载

转载 作者:行者123 更新时间:2023-12-04 08:22:51 26 4
gpt4 key购买 nike

我目前正在学习Kotlin - Operator Overloading
我试图理解(通过一个例子)运算符重载如何为函数的 invoke() 工作。功能

前测

  • Kotlin's Extension Functions
    fun exampleOfExtensionFunction() {
    fun Int.randomize(): Int {
    return Random(this.toLong()).nextInt()
    }

    val randomizedFive = 5.randomize()
    println("$randomizedFive")
    }

    打印 :

    -1157408321

  • In Kotlin, functions can be declared as variables with types
    fun exampleOfFunctionType() {
    val printNumber: (number: Int) -> Unit
    printNumber = { number ->
    println("[$number = ${number.toString(16).toUpperCase()} = ${number.toString(2)}]")
    }

    printNumber(1023)
    }

    打印 :

    [1023 = 3FF = 1111111111]

  • Kotlin allows operator overloading with both extension and member functions
    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}")
    }

    打印 :

    { "one" , "two" , "three" }
    (myType.contains("four")) = false , ("three" in myType) = 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)
    }

    打印 :

    func1 body
    func2 body



    预期的 :

    Overloaded invoke operator
    Overloaded invoke operator



    另一个问题 :
    这究竟是什么? (如果不是运算符重载)
            operator fun ((Boolean, Boolean, Boolean) -> Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
    println("Overloaded invoke operator")
    return flag1 && flag2 && flag3
    }

    最佳答案

    正如在另一个答案中所说,调用是在函数对象本身上定义的,因此您不能使用扩展方法覆盖它。

    不过,我认为这里更深层次的问题是对该功能的目的略有误解。来看看plus对于+运算符。

    我想你会同意尝试定义 operator fun Int.plus(b: Int): Int { /* ... */}没有意义,因为覆盖默认值 +整数运算符是一件非常危险的事情,是吗?

    但是,如果您定义复数类:

    data class Complex(real: Double, img: Double)

    然后将其定义为对复数求和是完全合理的:
    operator fun Complex.plus(other: Complex): Complex {
    val real = this.real + other.real
    val img = this.img + other.img
    return Complex(real, img)
    }

    所以,与 invoke 相同和 () : () 的含义是它类似于为您的类型调用函数并覆盖 invoke在已经是功能的东西上只是自找麻烦。您想要使用它的目的是为您自己的对象提供类似函数的语法。

    例如,假设您定义了一个这样的接口(interface):
    interface MyCallback {
    fun call(ctx: MyContext)
    }

    您使用通常的方式:
    callback.call(ctx)

    但是通过 invoke 的实现运算符重载,您可以将其用作函数:
    operator fun MyCallback.invoke(ctx: Context) = this.call(ctx)

    /* Elsewhere... */
    callback(ctx)

    希望澄清您如何使用 invoke/ ()

    关于operator-overloading - Kotlin - 函数的调用运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43149909/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com