Golang Map Addressability

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

 

http://wangzhezhe.github.io/blog/2016/01/22/golangmapaddressability-dot-md/

 

在golang中關於map可達性的問題(addresable?)

在go playground中有這樣的例子:

12345678910111213141516
package mainimport (  "fmt")type Type struct {  A string}func main() {  items := make(map[string]Type)  items["q"] = Type{}  items["q"].A = "abc"  fmt.Println(items)}

這樣在執行的時候會報一個常見的錯誤:cannot assign to items["q"].A

改變一下value的聲明方式,之後再進行類似的操作就可以了:

12345678910111213141516
package mainimport (  "fmt")type Type struct {  A string}func main() {  items := make(map[string]*Type)  items["q"] = &Type{}  items["q"].A = "abc"  fmt.Printf("%+v", items)}

在golang設計的時候,map中的value值應該是地址不可達的,就是說直接取map中的元素的地址會報錯,比如把上面例子中的main函數改成下邊這樣:

1234
itemsb := make(map[string]Type)itemsb["p"] = Type{3}pointer := &itemsb["p"]fmt.Println(pointer)

會報出cannot take the address of itemsb["p"]的錯誤。原因大致是因為,在golang中,一個容量不斷增長的map可能會導致原來map中的一些元素髮生rehashing,使得他們被重新分配到新的storage location上,這樣可能會導致原先得到的address變得不可用。就是所謂的map member 的 not addresable。

正如這個答案中寫的,map的indexing操作本來就是地址不可達的,這和golang中map的具體實現機制有關,golang中的map並沒有保證它們的value值的地址是不可變的,因為value值的地址很有可能被重新分配,就像前面所說的那樣。一個修改的辦法就是把value值設定成為指標的形式,這樣就相當於添加了一個額外的entry,即使真正需要的那個值的位置發生了變化,也可以redirection過去。以後使用map聲明一個結構體的value值的時候,這一點要特別注意下。

對於slice的index操作就是地址可達的,對於map則是不可達的,總是使用map的時候要特別注意下。

??map is a reference to the map contents, but it does not hold references (unless it explicitly stores pointers).

相關參考:

https://golang.org/ref/spec#Address_operators

https://code.google.com/p/go/issues/detail?id=3117

https://groups.google.com/forum/#!topic/golang-nuts/4_pabWnsMp0

https://golang.org/ref/spec

http://stackoverflow.com/questions/13101298/calling-a-pointer-method-on-a-struct-in-a-map https://golang.org/ref/spec#Address_operators

http://stackoverflow.com/questions/16059038/can-not-assign-to-a-struct-member-from-map

首先要明確一下,在聲明的時候&Type{}與Type{}的區別在哪裡

currently map member並非是addressable的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.