私はJava 8 + Groovy 2.4.12を持っており、以下のコードをコンパイルして実行します。Groovy呼び出しの汎用メソッドはコンパイルされません
import java.util.function.Consumer
import groovy.transform.CompileStatic
@CompileStatic
class Bar {
public static <T> void foo(T a, Consumer<T> c) { c.accept(a) }
static void main(args) {
['a','b'].each {
int xyz
xyz = 1
foo('') {
println '1'
return
}
}
}
}
は、しかし、あなたがreturn
をコメントアウトした場合、コンパイラはあなたがxyz
値の割り当てをコメントアウトした場合、それは再び大丈夫だ、さらに上の
Groovy:[Static type checking] - Cannot call <T> Bar#foo(T, java.util.function.Consumer <T>) with arguments [java.lang.String, groovy.lang.Closure
を言います。だから、次のコードはコンパイルと実行が:
@CompileStatic
注釈を- 二つのパラメータを持つジェネリックメソッド;:
['a','b'].each { int xyz // xyz = 1 foo('') { println '1' // return } }
これは、あなたが持っている場合にのみ発生する特殊な条件です第1引数はジェネリック型であり、第2引数は同じジェネリック型のインターフェイスである。
- その汎用メソッドへの呼び出し、第2引数はクロージャとして呼び出され、すべてが別のクロージャでラップされる。
- (
int xyz = 1
ような差がない場合、2つの別々の行に又は単一ライン上の)コールの前に変数の宣言と値割り当て
私の質問です。これはコンパイラのバグですか、それともreturn
の文がなくてもコンパイルされないのに合理的な理由がありますか?あるいは、なぜ変数定義を追加するとそれが壊れますか?
私は、コンシューマーにクロージャをキャストする必要があると思います。 – cfrick
@cfrickはい、これが可能な回避策の1つです。しかし、私はむしろこれが予想される動作か、コンパイラのバグかを知りたいと思っていました。 JeffはJIRAチケットをApacheに提出したので、私は彼らの意見を待つだろうと思う。しかし、ありがとう。 –