java - 为什么在 Java 中实现返回 Unit 的 Kotlin 函数时必须返回 Unit.

如果我有一个 Kotlin 函数

fun f(cb: (Int) -> Unit)

我想从 Java 中调用 f,我必须这样做:

f(i -> {
     dosomething();
     return Unit.INSTANCE;
});

看起来很丑。为什么我不能像 f(i -> dosomething()); 这样写,因为 Kotlin 中的 Unit 等价于 void java ?

最佳答案

Unit在 Kotlin 中主要相当于 void在 Java 中,但是只有在 JVM 规则允许的情况下。

Kotlin 中的函数类型由如下接口(interface)表示:

public interface Function1<in P1, out R> : Function<R> {
    /** Invokes the function with the specified argument. */
    public operator fun invoke(p1: P1): R
}

当您声明 (Int) -> Unit ,从 Java 的角度来看,这相当于 Function<Integer, Unit> .这就是为什么你必须返回一个值。为了解决这个问题,在 Java 中有两个单独的接口(interface) Consumer<T>Function<T, R>当你没有/没有返回值时。

Kotlin 设计者决定放弃功能接口(interface)的重复,转而依赖编译器的“魔法”。如果您在 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;
        };
    }
}

用法:

f(fromConsumer(integer -> doSomething()));

趣事:Unit 的特殊处理通过 Kotlin 编译器,您可以编写如下代码:

fun foo() {
    return Unit
}

fun bar() = println("Hello World")

两种方法都有返回类型 void在生成的字节码中,但编译器足够聪明,可以弄清楚并允许您使用返回语句/表达式。

关于java - 为什么在 Java 中实现返回 Unit 的 Kotlin 函数时必须返回 Unit.INSTANCE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37828790/

相关文章:

android - 如何在 kotlin 中使用 Android Support typedef 注

input - 在 Kotlin 中读取控制台输入

android - Android 中的 AsyncTask 与 Kotlin

kotlin - 如何将可变集合变成不可变集合

kotlin - 无需额外对象分配的数组/列表迭代

properties - Kotlin 中是否有 didSet/willSet 模拟?

android - kotlin 和 ArgumentCaptor - IllegalStateEx

java - 为 Kotlin 创建 POJO 类

kotlin - 'by' 关键字在 Kotlin 中的作用是什么?

android - Unresolved reference DaggerApplicationCo