2011-02-09 20 views
4

說我想改變數組中所有對象的值。 我喜歡範圍語法不僅僅是命名爲循環。轉:您可以使用範圍與切片,但獲得參考? (迭代)

所以,我想:

type Account struct { 
    balance int 
} 
type AccountList []Account 
var accounts AccountList 
... 
.... 
// to init balances 
for _,a := range(accounts) { 
    a.balance = 100 
} 

的是,由於沒有工作距離爲accountList條目的副本,因此,我們只更新副本。

這不會因爲我需要它的工作:

for a := range(accounts) { 
    accounts[a].balance = 100 
} 

但是,代碼有內部的一個額外的查找for循環。

有沒有辦法做一個迭代器,獲取對AccountList中的結構的引用?

+1

是否有理由'AccountList`不能是`[] * Account`? – mkb 2011-02-09 18:26:28

回答

3

只要讓AccountList爲[] *帳戶。然後你會得到範圍內每個帳戶的指針。

+0

我想這在大多數情況下是有道理的。在垃圾收集器或內存緩存上使用[] Account可能會更容易,但這可能只是性能調整期間值得做的更改。 – 2011-02-12 18:00:01

3

問題是,通過使用您的第一個for/range循環,您可以通過變量a中的值獲取結構體。您使用的第二個/ range範圍循環通過直接訪問slice中的內存來解決問題。

但是,您在第二個for循環內部發生「額外」查找時不正確。循環條件只是檢查切片的長度並增加計數器直到達到最終。然後,accounts[a]表達式將實際執行數組查找並直接操縱內存。如果有的話,第二個for循環轉換爲更少的指令,因爲它不是首先將結構by-value的內容複製到變量中。

我認爲你擔心的是每次都必須參考accounts[i]。如果你想在裏面for循環的帳戶執行多個操作,我認爲解決這個問題會是這樣的最佳方式:

for i := range accounts { 
    a := &accounts[i] 
    a.balance = 100 
    // manipulate account A further... 
} 

其他可能的解決方案,MUE建議,就是簡單地擁有片保持指針。這樣做的方式有兩個好處,但不管你是在C還是在Go,這個困境都是一樣的。只需要多一點語法糖。

+0

你可以這樣做: accounts [i] .balance = 100 – Jessta 2011-02-18 06:21:52