Javaの呼び出し元に対する「無効」戻り値の型でKotlinラムダを宣言するには?

Chriss:

私は完全に公共のAPIを含むKotlinで書かれているライブラリを持っています。今、図書館の利用者は、Javaを使用して、ここでの問題は、戻り値の型を持つKotlinラムダは、ということであるUnit戻り値の型にコンパイルされていませんvoid効果は、Java側は返すために常に持っているということであるUnit.INSTANCE、事実な方法のためにvoidこれは何とか回避することはできますか?

例:

Kotlinラムダ

interface Foo{
  fun bar(x:(String)->Unit)
}

Javaのコール

public void call(){
   foo.bar(this::processString)
}

//the return type should rather be void instead of Unit
public Unit processString(String s){  
    return Unit.INSTANCE 
    // ^^ implementations should not be forced to return anything 
 }

それは、コンパイラが生成するので、異なるKotlinラムダを宣言することが可能であるvoid戻り値の型を?

参照Javaの呼び出し元に対する「無効」戻り値の型を持つKotlinの関数を宣言するためにどのように?

ローランド:

私は、私がアクセスなどKotlinのJavaからコード(または何私の心に来ている)に必要なこのような状況で何をしたか、私はこれに本当の答えを持っていないが、私は共有することになります。

基本的に、それはあなたが本当に向上させるだけで、必要なものを手に入れる/触れたい方によって決まります。

Javaの同等物をサポートするために、Kotlinコードの強化:

interface Foo {
  fun bar(x : (String) -> Unit)

  /* the following is only here for Java */
  @JvmDefault // this requires that you add -Xjvm-default=enable to your compiler flags!
  fun bar(x:Consumer<String>) = bar(x::accept)
}

これは、いくつかの欠点があります。Consumer-methodは、同様にKotlinから表示され、そこからもそのため呼び出し可能です。あなたはインタフェースですべての機能を複製し、したがって、あなたの全体のKotlin-インターフェースはちょうどより多くの肥大化を取得する必要があることは言うまでもないです。しかし:それは両側からあなたが期待するように動作します。Javaの呼び出しConsumer-variantを、Kotlinは呼び出す(String) -> Unit-variantを...うまくいけば;-)実際には、いくつかのコールをデモ:

// from Java:
..bar(s -> { System.out.println(s); })
// however, method references might not work that easily or not without a workaround...
..bar((Consumer<String>) System.out::println); // not nice... @JvmName("kotlinsBar") to the rescue? well... that will just get more and more ugly ;-)

// from Kotlin:
..bar(Consumer(::println)) // or: ..bar(Consumer { println(it) })
..bar(::println)           // or: ..bar { println(it) } // whatever you prefer...

別の変形は、以下のように、例えば何かを実際に助けをJavaからKotlinの機能を簡単に呼び出すヘルパーメソッドを追加することで、言ったこと:

fun <T> `$`(consumer: Consumer<T>): (T) -> Unit = consumer::accept

おそらくKotlinから呼ばれることはありませんどの($と組み合わせるバッククォートを書いとしては、すでに面倒十分である)、または、あなたのKotlinのコードを膨張させたくない場合は、単にしかし、それはそのスリムに見えないJava、このようなメソッドを追加します:

static <T> Function1<T, Unit> $(Consumer<T> consumer) {
    return t -> {
        consumer.accept(t);
        return Unit.INSTANCE;
    };
}

これらのメソッドの呼び出しは両方とも同じに見えます。

..bar($(s -> /* do something with s */)) // where bar(x : (String) -> Unit)

物事のために私は、私はちょうど戻っ解決するために必要Unit.INSTANCEnull、私はより多くのメソッドを持っていた場合、私はおそらく第二(選択しているだろう呼び出すために$(...))アプローチを。私が唯一の供給に必要な最良の場合には(生成?;-))相当一度と供給のに対し、いくつかのプロジェクトでそれらを使用defaultするJavaはおそらく道より多くの作業が必要になりますし、さらにいくつかの人々を混乱させる可能性だけのためのインタフェースでバリアントを...

最後に:いいえ...私はあなたのような何か持っていることを可能にする任意のオプションを知らないvoidのうち官能性インターフェース(/消費者)UnitKotlinの-returning機能インタフェースを。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=137867&siteId=1