2016-02-02 16 views
7

Nel codice seguente, perché Groovy sembrano ignorare la dichiarazione di tipo generico fornito del parametro chiusura nel metodo barMany:Chiusura di tipo generico - anomalia

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> {} 

Aggiornamento: Groovy Versione: 2.4.5 JVM: 1.7.0_80 Venditore: Oracle Corporation SO: Linux

Aggiornamento Quindi c'era questo strano errore che non ho notato prima - org .codehaus.groovy.control.MultipleCompilationErrorsException: Avvio non riuscito - vi posterò piena potenza:

~/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/ 

Aggiornamento

Alcune altre soluzioni alternative per la completezza: Queste soluzioni alternative sembrano funzionare:

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! 

Lo stesso problema si applica anche quando un tipo è di una classe basata su T generico:

@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

Quale versione di groovy? –

+0

Ho aggiornato - scuse. –

+0

Non ho problemi con questo codice, prova a riavviare IDE. Non ho idea del perché dice errore. – Fincio

risposta

0

Questo era uno dei prodotti generici bugs che sono stati corretti in Groovy 2.4.6.