Why does Go forbid taking the address of (&) map member, yet allows (&) slice element?

后端 未结 2 1824
野的像风
野的像风 2020-12-04 22:30

Go doesn\'t allow taking the address of a map member:

// if I do this:
p := &mm[\"abc\"]
// Syntax Error - cannot take the address of mm[\"abc\"]
         


        
2条回答
  •  Happy的楠姐
    2020-12-04 23:04

    A fundamental difference between map and slice is that a map is a dynamic data structure that moves the values that it contains as it grows. The specific implementation of Go map may even grow incrementally, a little bit during insert and delete operations until all values are moved to a bigger memory structure. So you may delete a value and suddenly another value may move. A slice on the other hand is just an interface/pointer to a subarray. A slice never grows. The append function may copy a slice into another slice with more capacity, but it leaves the old slice intact and is also a function instead of just an indexing operator.

    In the words of the map implementor himself:

    https://www.youtube.com/watch?v=Tl7mi9QmLns&feature=youtu.be&t=21m45s "It interferes with this growing procedure, so if I take the address of some entry in the bucket, and then I keep that entry around for a long time and in the meantime the map grows, then all of a sudden that pointer points to an old bucket and not a new bucket and that pointer is now invalid, so it's hard to provide the ability to take the address of a value in a map, without constraining how grow works... C++ grows in a different way, so you can take the address of a bucket"

    So, even though &m[x] could have been allowed and would be useful for short-lived operations (do a modification to the value and then not use that pointer again), and in fact the map internally does that, I think the language designers/implementors chose to be on the safe side with map, not allowing &m[x] in order to avoid subtle bugs with programs that might keep the pointer for a long time without realizing then it would point to different data than the programmer thought.

    See also Why doesn't Go allow taking the address of map value? for related comments.

提交回复
热议问题