2012-05-23 17 views
6

Sto leggendo "Groovy in Action" di recente. Nel capitolo 7, ha introdotto il *. operatore. Quando eseguo il codice su questo operatore, ottengo alcuni errori.Groovy *. Operatori

class Invoice {           
    List items           
    Date date           
}               
class LineItem {           
    Product product          
    int  count           
    int total() {           
     return product.dollar * count      
    }              
}               
class Product {           
    String name           
    def  dollar          
}               

def ulcDate = new Date(107,0,1) 
def ulc = new Product(dollar:1499, name:'ULC')   
def ve = new Product(dollar:499, name:'Visual Editor') 

def invoices = [           
    new Invoice(date:ulcDate, items: [     
     new LineItem(count:5, product:ulc),    
     new LineItem(count:1, product:ve)     
    ]),             
    new Invoice(date:[107,1,2], items: [     
     new LineItem(count:4, product:ve)     
    ])             
]               

//error 
assert [5*1499, 499, 4*499] == invoices.items*.total() 

L'ultima riga genererà un'eccezione. In un primo momento, posso spiegare perché questo errore è accaduto. Le invocie sono una lista e il tipo di elemento è una fattura. Quindi, usando direttamente gli oggetti si commette un errore. Provo a risolverlo usando invoices.collect{it.items*.total()}

Ma si ottiene comunque un errore. Quindi, come posso far valere il successo e perché le fatture * .items * .total() generano un'eccezione.

risposta

7

Il risultato dell'operatore invoices*. è un elenco, quindi il risultato di invoices*.items è un elenco di elenchi. flatten() può essere applicato a un elenco e restituisce un elenco semplice, quindi è possibile utilizzarlo per creare un elenco di LineItems dall'elenco di elenchi di ListItems. È quindi possibile applicare total() ai suoi elementi utilizzando l'operatore diffusione:

assert [5*1499, 499, 4*499] == invoices*.items.flatten()*.total() 
+0

eccellente, grazie! – linuxlsx

5

Ciò non rispondere alla tua domanda, ma potrebbe essere meglio avere sempre a disposizione anche un metodo totale nella classe Fattura in questo modo:

int total() { 
    items*.total().sum() 
}       

È quindi possibile controllare questo con:

assert [5*1499 + 499, 4*499] == invoices*.total() 
+0

grazie, per me è molto utile. – linuxlsx