4

したがって、これらのシグネチャを持つ Java メソッドがいくつかあります (わかりやすくするために、注釈とコード本体を削除しました)。

public class JavaClass {
  public static <E extends CharSequence> E join(E... array) { ... }
  public static <E extends CharSequence> E join(CharSequence separator, E... array) { ... }
}

Kotlin には、「結合」メソッドを呼び出すコードがいくつかあります。

class KtClass {
    fun test(vararg array: String) {
        JavaClass.join(*array)
    }
}

ここまでは順調ですね; varargs を展開し、以前のメソッド シグネチャを呼び出します。おきえドッキー!

たとえば、「セパレータ」引数を使用して後者のメソッド シグネチャを呼び出したい場合に問題が発生します。

class KtClass {
    fun test(vararg array: String) {
        JavaClass.join("<br>", *array)
    }
}

このコードはコンパイルされません。コンパイラは、呼び出すメソッドを決定できません。エラー:

エラー:(5, 13) Kotlin: 型推論が完了しないと、次の候補から選択できません: public open fun join(vararg array: String!): String! JavaClass で定義 public open fun join(separator: CharSequence!, vararg array: String!): String! JavaClass で定義

Kotlin では非 Kotlin 関数の引数の名前付けが許可されていないため、引数に名前を付けることさえできません。

編集: Eジェネリック型パラメーターをJava メソッド ヘッダーのプレーンなString参照に置き換えたところ、機能しました! だから私はこれがジェネリック型またはそのようなものとの型推論の非互換性であると思いますか?



これは、スプレッド演算子(*)を使用する必要があると確信しています。しかし、varargs パラメーターarrayjoin使用しないと関数に渡すことができません。

Javaコードに触れずにこれを解決するにはどうすればよいですか?

はい、Array.joinToString 拡張関数があることは知っていますが、これはこの特定のケースのみを解決します。一般的な解決策を知る必要があります。

4

3 に答える 3

2

それはKotlin固有のものではないと思います。問題は、ジェネリック引数Eが型であるため、最初の引数の型が他の引数の型と同じであるため、実際にはあいまいCharSequenceな呼び出しになることです。join("separator", "word1", "word2")E == CharSequence

于 2017-01-05T19:42:47.767 に答える
1

相互運用の問題を解決するには、Java でヘルパー クラスを作成する必要があるようです。例えば:

public class JavaClassInterop {
    public static <E extends CharSequence> E joinSeparatedBy(CharSequence separator,
                                                             E... array) {
        return JavaClass.join(separator, array);
    }
}

次に、両方を呼び出すことができます。

import JavaClass.join
import JavaClassInterop.joinSeparatedBy

fun main(args: Array<String>) {
    join(*args)
    joinSeparatedBy("<br>", *args)
}
于 2017-01-05T20:16:38.977 に答える