私は完全に公共の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
戻り値の型を?
私は、私がアクセスなど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.INSTANCE
かnull
、私はより多くのメソッドを持っていた場合、私はおそらく第二(選択しているだろう呼び出すために$(...)
)アプローチを。私が唯一の供給に必要な最良の場合には(生成?;-))相当一度と供給のに対し、いくつかのプロジェクトでそれらを使用default
するJavaはおそらく道より多くの作業が必要になりますし、さらにいくつかの人々を混乱させる可能性だけのためのインタフェースでバリアントを...
最後に:いいえ...私はあなたのような何か持っていることを可能にする任意のオプションを知らないvoid
のうち官能性インターフェース(/消費者)Unit
Kotlinの-returning機能インタフェースを。