/
我有以下Java代码段,试图将其转换为Kotlin
kotlin 1.3.31
我对上述方法的不了解是一个方法声明,该声明以ArgumentMatcher作为返回类型,并且接口的方法在lambda表达式中执行,并返回生成的布尔值。如果我的解释有误,请纠正我。
但是,当我尝试将其转换为Kotlin
private ArgumentMatcher<List<Person> customArgumentMatcher(final int size) {
return argument -> argument.size() == size;
}
我收到以下错误:
private fun customArgumentMatcher(size: Int): ArgumentMatcher<List<Person>> {
return { argument -> argument.size == size }
}
非常感谢您的任何建议,
答案 0 :(得分:4)
为其他答案添加背景:
就Java互操作性而言,这是Kotlin中稍显尴尬的领域之一。但这是Kotlin本身就是一种更好的语言的不幸结果!我来解释一下...
当Java添加了lambda时,他们以某种方式(与之前的泛型一样)做到了这一点,以最小程度地改变了语言的工作方式。因此,他们没有使函数成为一流的类型。相反,他们奉行使用接口的现有做法。例如,如果您希望将ActionEvent
的信息告知您,则可以实现ActionListener
接口。这有一个称为actionPerformed()
的方法,它带有一个ActionEvent
参数。
他们不想更改任何方法的工作方式,因此在Java 8+中,lambda只是实现某些接口的一种更为简洁的方法。上下文(即您正在调用的方法,或您要为其分配的变量的类型)告诉编译器您想要哪种类型的接口,它必须是具有单一抽象方法(SAM)的“功能接口”,然后编译器生成一个实现。有一些优化,但是基本上是您在Java 7-中所做的。它的运行情况还不错,但是有很多尴尬的情况,因为函数没有完整的一流对象。
科特林,另一方面,确实具有正确的功能类型。这功能更强大,更灵活,但与Java的处理方式不符。
Kotlin编译器具有一些特殊情况,可以将lambda自动转换为Java SAM接口的实现。 (不过,在实现Kotlin接口时这并不适用,这会引起一些混乱。)
在将SAM实现lambda直接传递给方法的情况下,编译器可以推断其类型。 (就像@Slaw的第二个示例一样。)
但是在其他情况下,您需要在大括号之前指定接口名称。 (就像@Slaw的第一个示例一样。)
答案 1 :(得分:3)
由于ArgumentMatcher
是Java功能接口,因此您需要使用:
fun customArgumentMatcher(size: Int): ArgumentMatcher<List<Person>> {
return ArgumentMatcher { argument -> argument.size == size }
}
请参阅Kotlin参考资料的SAM Conversions部分。
您还可以使用:
fun customArgumentMatcher(size: Int) = ArgumentMatcher<List<Person>> { it.size == size }
请参阅gidds' answer,以了解为什么需要上述语法的一些背景。