2012-05-23 182 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

這不回答你的問題,但它可能是更好的做法,也有一個總的方法在你的發票類,像這樣:

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

可以再用檢查:

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

謝謝,這對我非常有用。 – linuxlsx