Ran*_*ku' 38 java kotlin kotlin-interop
如果我有Kotlin功能
fun f(cb: (Int) -> Unit)
Run Code Online (Sandbox Code Playgroud)
我想用f
Java 调用,我必须这样做:
f(i -> {
dosomething();
return Unit.INSTANCE;
});
Run Code Online (Sandbox Code Playgroud)
这看起来很丑陋.为什么我不能这样写f(i -> dosomething());
,因为Unit
在Kotlin中相当于void
Java?
Kir*_*man 45
Unit
在Kotlin中,大多数情况下void
与Java相同,但只有当JVM的规则允许时才这样.
Kotlin中的功能类型由以下接口表示:
public interface Function1<in P1, out R> : Function<R> {
/** Invokes the function with the specified argument. */
public operator fun invoke(p1: P1): R
}
Run Code Online (Sandbox Code Playgroud)
当您声明时(Int) -> Unit
,从Java的角度来看,这相当于Function<Integer, Unit>
.这就是你必须返回一个值的原因.要解决这个问题,在Java中有两个独立的接口Consumer<T>
,Function<T, R>
当你没有/有一个返回值时.
Kotlin设计师决定放弃功能接口的重复,而是依赖编译器"魔术".如果在Kotlin中声明lambda,则不必返回值,因为编译器会为您插入一个值.
为了使您的生活更轻松一点,你可以写一个封装了一个辅助方法Consumer<T>
中Function1<T, Unit>
:
public class FunctionalUtils {
public static <T> Function1<T, Unit> fromConsumer(Consumer<T> callable) {
return t -> {
callable.accept(t);
return Unit.INSTANCE;
};
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
f(fromConsumer(integer -> doSomething()));
Run Code Online (Sandbox Code Playgroud)
有趣的事实:Unit
Kotlin编译器的特殊处理是您可以编写如下代码的原因:
fun foo() {
return Unit
}
Run Code Online (Sandbox Code Playgroud)
要么
fun bar() = println("Hello World")
Run Code Online (Sandbox Code Playgroud)
这两种方法void
在生成的字节码中都有返回类型,但编译器足够聪明,可以解决这个问题并允许您使用return语句/表达式.
归档时间: |
|
查看次数: |
9341 次 |
最近记录: |