2011-02-09 57 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