如何在 .kt 中使用功能接口 class

How to use functional-interface inside .kt class

我想使用 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 });

}

您可以使用以下语法实现您想要的(SAM 转换):

enum class Operation private constructor(private val symbol: String, private val op: DoubleBinaryOperator) {
    PLUS("+", DoubleBinaryOperator { left, right -> left + right }),
    ...
}

请注意,这仅适用于实现 Java 接口,如记录 here

编辑

为了扩展我在下面的评论,可以使用 Kotlin lambdas 代替功能接口(所谓的 SAM 转换) 调用 Java 代码时科特林。这在纯 Kotlin 中是不允许的,因为您可以使用函数类型(例如,(Double, Double) -> Double,模仿 DoubleBinaryOperator)。

例如,考虑以下 Java class:

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 的编译错误:“Required Supplier, found () -> String”(这与您遇到的问题相同)因为无法进行 SAM 转换。但是,您可以使用 SAM 构造函数(即用例 2)“强制”它。