為什么我要返回單位。在Java中實現返回單元的Kotlin函數時?

[英]Why do I have to return Unit.INSTANCE when implementing in Java a Kotlin function that returns a Unit?


If I have a Kotlin function

如果我有一個Kotlin函數

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

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

我想從Java調用f,我必須這樣做:

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

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?

這看起來很丑。為什么不能寫成f(I -> dosomething());因為Kotlin中的單元在Java中等同於void ?

1 个解决方案

#1


21  

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

然而,Kotlin中的單元在Java中幾乎等同於void,不過只有在JVM的規則允許的情況下才會這樣。

Functional types in Kotlin are represented by interfaces like:

Kotlin中的功能類型由如下接口表示:

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

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.

當您聲明(Int) ->單元時,從Java的角度來看,這相當於函數 。這就是為什么你要返回一個值。為了解決這個問題,在Java中有兩個獨立的接口,消費者 和函數

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.

Kotlin設計人員決定放棄功能接口的重復,轉而依賴於編譯器“魔法”。如果您在Kotlin中聲明一個lambda,您不必返回一個值,因為編譯器將為您插入一個值。

To make your life a little bit easier, you can write a helper method that wraps a Consumer<T> in a Function1<T, Unit>:

為了使您的生活更簡單,您可以編寫一個助手方法,將消費者 包裝在Function1 :

public class FunctionalUtils {
    public static <T> Function1<T, Unit> fromConsumer(Consumer<T> callable) {
        return t -> {
            callable.accept(t);
            return Unit.INSTANCE;
        };
    }
}

Usage:

用法:

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

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

有趣的事實:Kotlin編譯器對單元的特殊處理是您可以編寫代碼的原因:

fun foo() {
    return Unit
}

or

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

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.

這兩種方法在生成的字節碼中都有返回類型void,但是編譯器足夠聰明,可以計算出來,並允許您使用return語句/表達式。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2016/06/15/725c1e7b63493e7817e04e7e34c76d9b.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com