我想在java.util.function
包中使用某些功能接口,例如DoubleBinaryOperator
接口。
我可以在Java中使用它,如下所示:
public enum Operation {
PLUS("+", Double::sum),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
}
但是在Kotlin中,这对我不起作用,因为Kotlin无法推断参数的类型。
enum class Operation private constructor(private val symbol: String, private val op: DoubleBinaryOperator) {
PLUS("+", { x, y -> x + y }),
MINUS("-", { x, y -> x - y }),
TIMES("*", { x, y -> x * y }),
DIVIDE("/", { x, y -> x / y });
}
答案 0 :(得分:1)
您可以使用以下语法实现所需的功能(SAM转换):
enum class Operation private constructor(private val symbol: String, private val op: DoubleBinaryOperator) {
PLUS("+", DoubleBinaryOperator { left, right -> left + right }),
...
}
请注意,这仅适用于实现Java接口,如here所述。
为进一步说明我的意见,在从Kotlin调用Java代码时,只能 使用Kotlin lambda代替功能接口(即SAM转换)。在纯Kotlin中,这是不允许的,因为您可以使用函数类型(例如,(Double, Double) -> Double
来模仿DoubleBinaryOperator
)。
作为示例,请考虑以下Java类:
public class MyClass {
String append(String input, Supplier<String> supplier) {
return input.concat(supplier.get());
}
}
在Kotlin中,您可以像这样使用它:
val myClass = MyClass()
// Use case 1
myClass.append("something") {
"suffix"
}
// Use case 2
myClass.append("Something", Supplier { "suffix" })
请注意,我的IDE告诉我在用例2中有一个“冗余SAM构造函数”。
现在,让我们用Kotlin重写MyClass
:
class MyClass {
fun append(input: String, supplier: Supplier<String>): String {
return input + supplier.get()
}
}
如果我们不使用代码进行更改,则将发生用例1的编译错误:“所需的供应商,找到()->字符串”(这与您遇到的问题相同),因为SAM转换无法完成。但是,您可以使用SAM构造函数“强制”使用它(即用例2)。