为什么在 Java 中实现返回 Unit 的 Kotlin 函数时必须返回 Unit.INSTANCE? [英] Why do I have to return Unit.INSTANCE when implementing in Java a Kotlin function that returns a Unit?

查看:20
本文介绍了为什么在 Java 中实现返回 Unit 的 Kotlin 函数时必须返回 Unit.INSTANCE?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个 Kotlin 函数

If I have a Kotlin function

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

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

and I want to call f from Java, I have to do it like:

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

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

which looks very ugly. Why can't I just write it like f(i -> dosomething());, since Unit in Kotlin is equivalent to void in Java?

推荐答案

Unit 在 Kotlin 中大部分等价于 Java 中的 void,但是只有当 JVM 的规则允许.

Unit in Kotlin is mostly equivalent to void in Java, however only when the rules of the JVM allow it.

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

Functional types in Kotlin are represented by interfaces like:

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.这就是为什么你必须返回一个值.为了解决这个问题,在 Java 中有两个单独的接口 ConsumerFunction 用于当您没有/有返回值时.

When you declare (Int) -> Unit, from Java's point of view this is equivalent to Function<Integer, Unit>. That's why you have to return a value. To work around this problem, in Java there are two separate interfaces Consumer<T> and Function<T, R> for when you don't have/have a return value.

Kotlin 设计者决定放弃函数式接口的重复,转而依赖编译器的魔法".如果你在 Kotlin 中声明了一个 lambda,你不必返回一个值,因为编译器会为你插入一个值.

The Kotlin designers decided to forgo the duplication of functional interfaces and instead rely on compiler "magic". If you declare a lambda in Kotlin, you don't have to return a value because the compiler will insert one for you.

为了让您的生活更轻松,您可以编写一个辅助方法,将 Consumer 包装在 Function1 中::>

To make your life a little bit easier, you can write a helper method that wraps a Consumer<T> in a 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()));

<小时>

有趣的事实:Kotlin 编译器对 Unit 的特殊处理是您可以编写如下代码的原因:


Fun fact: The special handling of Unit by the Kotlin compiler is the reason you can write code like:

fun foo() {
    return Unit
}

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

这两种方法在生成的字节码中都有返回类型void,但编译器足够聪明,可以解决这个问题,并允许您无论如何都使用返回语句/表达式.

Both methods have return type void in the generated bytecode but the compiler is smart enough to figure that out and allow you to use return statements/expressions anyway.

这篇关于为什么在 Java 中实现返回 Unit 的 Kotlin 函数时必须返回 Unit.INSTANCE?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆