Kotlin:lambda从不编译

我刚刚开始学习Kotlin,在那里我遇到了lambda语法问题。 有一个小例子:

class MathFunctions { @FunctionalInterface interface Operation { fun calculate(a: Int, b: Int): Int } fun makeCalculations(a: Int, b: Int, operation: Operation): Int = operation.calculate(a, b) companion object { @JvmStatic fun main(args: Array) { val plus = Operation { a, b -> a + b } val mathFunctions = MathFunctions() println(mathFunctions.makeCalculations(10, 20, plus)) } } } 

这个类从来没有编译过,因为lambda有些问题。 在Java中是这样的:

 public class MathFunctions { @FunctionalInterface interface Operation { int calculate(int a, int b); } public int makeCalculations(int a, int b, Operation operation) { return operation.calculate(a, b); } public static void main(String[] args) { Operation plus = (a, b) -> a + b; MathFunctions example = new MathFunctions(); System.out.println(example.makeCalculations(10, 20, plus)); } } 

什么应该纠正? 我已经尝试了从Intellij Idea的Java到Kotlin的自动转换,并且失败了。

你的代码的问题是,Kotlin 不允许SAM转换成在Kotlin中编写的接口 。 这个限制的原因是Kotlin具有内置在语言中的函数types ,应该使用它们(或者回退到匿名对象expression式 )。

你可以重写你的代码来:

 class MathFunctions { fun makeCalculations(a: Int, b: Int, operation: (Int, Int) -> Int): Int = operation(a, b) companion object { @JvmStatic fun main(args: Array) { val plus: (Int, Int) -> Int = { a, b -> a + b } val mathFunctions = MathFunctions() println(mathFunctions.makeCalculations(10, 20, plus)) } } } 

为了使代码更具可读性,您可以使用types别名 :

 typealias Operation = (Int, Int) -> Int 

如果您严格要将java代码翻译成kotlin,答案是:

 fun main(args: Array) { val plus = object : MathFunctions.Operation { override fun calculate(a: Int, b: Int) = a + b } val mathFunctions = MathFunctions() println(mathFunctions.makeCalculations(10, 20, plus)) } class MathFunctions { @FunctionalInterface interface Operation { fun calculate(a: Int, b: Int): Int } fun makeCalculations(a: Int, b: Int, operation: Operation): Int = operation.calculate(a, b) } 

但是如果你有选择,也许你更喜欢下面的方式保持操作不像界面蝙蝠一样的lambda参数:

 fun main(args: Array) { val mathFunctions = MathFunctions() println(mathFunctions.makeCalculations(10, 20, { a, b -> a + b})) } class MathFunctions { fun makeCalculations(a: Int, b: Int, operation: (Int, Int) -> Int): Int = operation(a, b) } 

Kotlin尚未支持Kotlin接口的SAMfunction接口。 它仅支持Java接口的SAM。 其他原因已经被描述。 但是,由于SAM范例在Java中无处不在,而且由于Kotlin采用者通常将Java转换为Kotlin,并且由于大部分代码需要移植SAM,所以他们可能会开始在Kotlin接口上支持SAM。

答案(现在)是使用一个对象文字,希望lambda转换。

 println(mathFunctions.makeCalculations(10, 20, object : Operation { override fun calculate(a:Int, b:Int):Int { return a+b } })) 

这里是关于支持该function的讨论。