目前我正在Kotlin - Operator Overloading
我想了解(用一個例子)的函數的invoke()
功能科特林 - 函數調用運算符重載
預測試如何操作符重載工作
-
個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}") }
打印:
{ 「一」, 「二」, 「三」}
(myType.contains( 「四」))=假,(」三個」的myType)=真
測試嘗試
根據以上所述。我嘗試使用類型(Boolean, Boolean, Boolean) -> Boolean
作爲擴展函數invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean)
的接收器類型創建函數invoke()
運算符重載的示例。然而,這並沒有按預期那樣工作。
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體
FUNC2體
預計:
重載調用運營商
重載調用操作
另一個問題:
究竟這是什麼道理? (如果不是運營商超載)
operator fun ((Boolean, Boolean, Boolean) -> Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
println("Overloaded invoke operator")
return flag1 && flag2 && flag3
}
原因是,如果擴展的優先級高於成員函數,函數調用的結果可能是不確定的,並且可以通過簡單地在您的項目中包含另一個庫而不需要知道(假定擴展名在範圍內或導入)。 –
這是否意味着無法有效地重載調用函數?因爲每次成員函數都優先。而且因爲沒有辦法在kotlin中定義一個函數類型的類,所以實現運算符重載作爲函數的成員函數。 – naaz
對於函數類型是的,但任何具有開放調用函數的類都可以被覆蓋。功能類型的要點是接受與簽名匹配的任何內容。和其他任何東西一樣,如果你想要特定的功能,你可以創建一個具有該功能的類。 –