我在Kotlin中有以下功能
fun evaluate(first:Int?, second:Int?) {
var result = 0
if (v.equals('*')) {
result = (first ?: 0) * (second ?: 0)
} else if (v.equals('+')) {
result = (first ?: 0) + (second ?: 0)
} else if (v.equals('-')) {
result = (first ?: 0) - (second ?: 0)
} else if (v.equals('/')) {
result = (first ?: 0) / (second ?: 0)
}
return result
}
我想以某种方式更改它,以便我可以作为第三个参数传递所需的运算符并评估表达式。像
这样的东西fun evaluate(first:Int?, second:Int?, op: () -> Unit):Int {
return (first ?: 0).op(second ?: 0)
}
在这种情况下,如何将运算符作为函数传递?我检查了同一种question,但目前尚不清楚如何通过运营商来做到这一点。
答案 0 :(得分:7)
使用higher order function作为参数编写function type允许使用内置运算符和lambda expressions进行操作,因此看起来像这样:
fun evaluate(first: Int?, second: Int?, op: (Int, Int) -> Int): Int {
return op(first ?: 0, second ?: 0)
}
可以使用内置运算符调用,例如:
val r1 = evaluate(value1, value2, Int::times)
val r2 = evaluate(value1, value2, Int::plus)
val r3 = evaluate(value1, value2, Int::minus)
val r4 = evaluate(value1, value2, Int::div)
使用自定义功能:
val r5 = evaluate(value1, value2) { a, b -> (a * a) + b }
现在您还可以将运算符分配给变量,例如v
:
val v: (Int, Int)->Int = Int::times // typing needed on left to avoid ambiguous alternatives
// and then later...
val r6 = evaluate(value1, value2, v)
请注意,为签名Int.(Int)->Int
编写的函数可以传递到期望(Int, Int)->Int
的参数中,因为接收器this
将作为第一个参数传入。
答案 1 :(得分:0)
将() -> Unit
更改为Int.(Int) -> Int
。然后所有其他代码应该按照你在那里编写的那样工作。
在调用方面,this
是第一个int,第一个参数是第二个int:{ other -> this * other }
答案 2 :(得分:0)
你可以尝试这样做:
fun evaluate(first: Int?, second: Int? , v:String ): Int = v.op(first ?: 0, second ?: 0)
fun String.op(first:Int,second:Int):Int = when (this) {
"*" -> first * second
"+" -> first + second
//....
else -> throw Exception()
}
fun main(args: Array<String>) {
println(evaluate(2,3,"*"))
println(evaluate(2,3,"+"))
}