Kotlin: 使用Pair<Int, Int>以惯用方式调用(Int, Int) -> Int的方法?

4
fun sum(a: Int, b: Int) = a + b
val x = 1.to(2)

我正在寻找以下内容的翻译,与IT技术有关:
  1. sum.tupled(x),或者
  2. sum(*x)
当然,以上内容都无法在Kotlin 1.1.3-2中编译。那么我只能使用sum(x.first, x.second)吗? 编辑: 综合有用的答案,我认为现在最接近的是:
fun <P1, P2, R> Function2<P1,P2,R>.tupled(x: Pair<P1, P2>): R = invoke(x.first, x.second)
3个回答

1

了解您的需求后,我认为您根本不需要任何过载函数/扩展函数,只需使用KCallable#call即可,例如:

val x  = arrayOf(1, 2)

//                v--- top-level  functions 
val result:Int = ::sum.call(*x) 
//                  v--- member-level  functions 
val result:Int = this::sum.call(*x) 

你也可以像Java一样在Kotlin中重载函数sum,例如:

sum(1 to 2)
sum(*intArrayOf(1, 2))

fun sum(tuple: Pair<Int, Int>) = sum(tuple.first, tuple.second)

fun sum(vararg pair: Int) = sum(pair[0], pair[1])

对于 sum.tupled(x),你可以编写一个扩展函数,例如:

val sum: (Int, Int) -> Int = ::sum // top-level function
//OR
val sum:(Int, Int)->Int = this::sum // member scope function


// the final form is what you want 
//                       v
val result:Int = sum.tupled(1 to 2)

fun <T1,T2,R> Function2<T1,T2,R>.tupled(x:Pair<T1,T2>):R = invoke(x.first,x.second)

1
你在 intArray 中打错了,应该是 IntArray。但更重要的是 sum(*IntArray(1, 2)) 无法编译通过。第二个 Int 与构造函数 IntArray(size: Int, init: (Int) -> Int)init 函数冲突。 - Abhijit Sarkar
@Abhijit Sarkar,是的,我没有编辑器,只有两只手。谢谢 :) - holi-java
1
你能帮我理解tupled扩展函数吗?(我是 Kotlin 的新手)invoke是在Function2中定义的,对吧?所以你是将相同的数字加到自身上吗?这不会是我问题中的sum - Abhijit Sarkar
1
@Abhijit Sarkar 你好,这是 Kotlin 内置类型的一种别名,即 (T,T)->R - holi-java
@Abhijit Sarkar 您好,您有原始的 sum(1,2),对吗?它需要两个 Int,对吗?请运行我的编辑后的答案,先生。 - holi-java
显示剩余6条评论

1
如果您想使用Kotlin的简洁语法,您可以编写以下内容:
val sum : (Pair<Int,Int>) -> Int = { (a,b) -> a + b }

现在,sum 不能用 2 个 Int 调用 :( - Abhijit Sarkar
我并不是要替换旧的总和,你可以保留它们两个,它们并不冲突。 - Seaskyways
那么你的答案类似于 @holi-java 的。我确信我可以拥有同一方法的两个不同版本,但如果语言能够为我完成这个任务就更好了。 - Abhijit Sarkar
请注意,解构声明不是参数类型的更改。您不能简单地(目前)将(Int, Int) -> Int用作(Pair<Int, Int>) -> Int。它们在内部工作方式上是不同的。 - Seaskyways
在系统内部,它调用了 Pair.component1()Pair.component2() 来填充变量,这些变量看起来像参数,但实际上它们不是。 - Seaskyways
需要一个“提升” :) - Abhijit Sarkar

0

扩展函数也是一种非常方便的方式:

fun Pair<Int, Int>.sum() = this.first + this.second
val x = 1.to(2)
x.sum()

那如果我还有 multiplysubtract 呢?为每个函数都创建一个扩展函数太麻烦了。 - Abhijit Sarkar
是的,但您只需完成一次工作,然后通过导入扩展函数即可在任何地方使用它。 - guenhter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接