2012-05-23 16 views
6

最近「Groovy in Action」と読みました。第7章では、*を導入しました。演算子。私はこの演算子についてのコードを実行すると、いくつかの間違いがあります。Groovy *。演算子

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

最後の行は例外をスローします。 まず、私はこのエラーが起こる理由を説明することができます。 invociesはListで、要素の型はInvoiceです。したがって、直接項目を使用するとエラーになります。私はそれを使用して修正しようとしましたinvoices.collect{it.items*.total()}

しかし、まだ失敗アサートを取得します。だから、私はどのようにアサーションを成功させることができ、なぜインボイス* .items * .total()が例外をスローするのか。

答えて

7

invoices*.の結果はリストなので、invoices*.itemsの結果はリストのリストです。 flatten()はリストに適用してフラットなリストを返すので、ListItemsのリストからLineItemsのリストを作成することができます。その後、拡散演算子を使用して、その要素にtotal()を適用することができます。

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

優れ、感謝を! – linuxlsx

5

これは、あなたの質問に答えていないが、またそうのようなあなたのInvoiceクラスの総メソッドを持っている優れた実践であるかもしれない:

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

あなたは、その後でこれを確認することができます。

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

ありがとう、それは私にとってとても便利です。 – linuxlsx