2012-05-23 17 views
6

Estoy leyendo 'Groovy in Action' recientemente. En el capítulo 7, introdujo el *. operador. Cuando ejecuto el código sobre este operador, obtengo algunos errores.Groovy *. Operadores

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() 

La última línea arrojará una excepción. Al principio, puedo explicar por qué ocurrió este error. La invocación es una lista y el tipo del elemento es Factura. Entonces, usar elementos directamente hará un error. Intento solucionarlo usando invoices.collect{it.items*.total()}

Pero aún así obtengo una declaración fallida. Entonces, ¿cómo puedo hacer que la declaración sea exitosa y por qué las facturas * .items * .total() emitirán una excepción.

Respuesta

7

El resultado del operador invoices*. es una lista, por lo que el resultado de invoices*.items es una lista de listas. flatten() se puede aplicar a una lista y devuelve una lista plana, por lo que puede usarla para hacer una lista de LineItems de su lista de lista de ListItems. A continuación, puede aplicar total() a sus elementos mediante el operador de difusión:

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

excelente, gracias! – linuxlsx

5

Esto no responde a su pregunta, pero podría ser mejor práctica tener también un método total en su clase Factura de este modo:

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

entonces usted puede comprobar esto con:

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

gracias, es muy útil para mí. – linuxlsx