2016-02-02 16 views
7

W poniższym kodzie, dlaczego Groovy wydaje się być ignorowanie dostarczonego oświadczenia typu rodzajowego parametru zamknięcia w metodzie barMany:Zamknięcie typu Generic - anomalii

import groovy.transform.CompileStatic 

@CompileStatic 
class Main { 
    static main(args) { 
     FooSub foo = new FooSub() 
     BarSub bar = new BarSub() 
    } 
} 

@CompileStatic 
class Foo<T> { 
    void fooOne (T item) {} 
    void fooMany(List<T> items) { 
     items.each { T item -> fooOne(item) } // Compiles fine. 
    } 
} 

@CompileStatic 
class FooSub extends Foo<Integer> {} 

@CompileStatic 
class Bar<T extends Bar<T>> {  
    void barOne (T item) {} 
    void barMany(List<T> items) { 

     items.each { T item -> barOne(item) } // Error: 
     // Cannot find matching method Bar#barOne(java.lang.Object) !!! 

     items.each { T item -> barOne(item as T) } // Error: 
     // Expected parameter of type java.lang.Object but got T !!! 

     items.each { item -> barOne(item as T) } // Compiles fine - closure knows about T 

    } 
    void barManyMore(List<T> items) { 
     for (T item in items) { // Compiles fine. 
      barOne(item) } 
    } 
} 

@CompileStatic 
class BarSub extends Bar<BarSub> {} 

aktualizacji: Groovy wersja: 2.4.5 JVM: 1.7.0_80 Producent: Oracle Corporation OS: Linux

Aktualizacja Więc nie było to dziwne błąd, że nie zauważyłem wcześniej - org .codehaus.groovy.control.MultipleCompilationErrorsException: starcie udało - wyślę pełną moc:

~/grov/tests$ groovyc generics.groovy 
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: 
generics.groovy: 27: Expected parameter of type java.lang.Object but got T 
@ line 27, column 19. 
     items.each { T item -> barOne(item) } // Error: 
        ^

generics.groovy: 27: [Static type checking] - Cannot find matching method Bar#barOne(java.lang.Object). Please check if the declared type is right and if the method exists. 
@ line 27, column 29. 
     items.each { T item -> barOne(item) } // Error: 
          ^

generics.groovy: 30: Expected parameter of type java.lang.Object but got T 
@ line 30, column 22. 
      items.each { T item -> barOne(item as T) } // Error: 
         ^

3 errors 

~/grov/tests$ groovyc -v 
Groovy compiler version 2.4.5 
Copyright 2003-2015 The Apache Software Foundation. http://groovy-lang.org/ 

Aktualizacja

Nieco więcej obejścia dla kompletności: Rozwiązania te wydają się działać:

Closure c = { T item -> barOne(item) }; items.each c // See comments by @tim_yates 
    items.each ({ T item -> barOne(item) } as Closure) // Casting to closure works too! 

Ta sama kwestia ma również zastosowanie, gdy typ jest klasą opartą na ogólnej T:

@CompileStatic 
class Baz<T extends Baz<T>> { 
    List<T> getList() { 
     return [new T(), new T()] 
    } 
} 

@CompileStatic 
class BazClient { 
    void useBaz(Baz baz) { 
     // baz.getList().each {Baz it -> println it} // Error 
     Closure c = {Baz it -> println it}; baz.getList().each c // works 
     baz.getList().each ({Baz it -> println it} as Closure) // works 
    } 
} 
+1

Która wersja groovy? –

+0

Zaktualizowałem - przepraszam. –

+0

Nie mam problemów z tym kodem, spróbuj ponownie uruchomić IDE. Nie mam pojęcia, dlaczego mówi błąd. – Fincio

Odpowiedz

0

To był jeden z produktów związanych z generycznymi bugs, które zostały naprawione w Groovy 2.4.6.