douhan8009 2015-09-10 07:12
浏览 55
已采纳

为什么Go禁止使用(&)映射成员的地址,却允许(&)slice元素?

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"]

The rationale is that if Go allows taking this address, when the map backstore grows or shinks, the address can become invalid, confusing the user.

But Go slice gets relocated when it outgrows its capacity, yet, Go allows us to take the address of a slice element:

 a := make([]Test, 5)
 a[0] = Test{1, "dsfds"}
 a[1] = Test{2, "sdfd"}
 a[2] = Test{3, "dsf"}

 addr1 := reflect.ValueOf(&a[2]).Pointer()
 fmt.Println("Address of a[2]: ", addr1)

 a = append(a, Test{4, "ssdf"})
 addrx := reflect.ValueOf(&a[2]).Pointer()
 fmt.Println("Address of a[2] After Append:", addrx)

 // Note after append, the first address is invalid
 Address of a[2]:  833358258224
 Address of a[2] After Append: 833358266416

Why is Go designed like this? What is special about taking address of slice element?

  • 写回答

2条回答 默认 最新

  • duanhe1903 2015-09-10 07:46
    关注

    There is a major difference between slices and maps: Slices are backed by a backing array and maps are not.

    If a map grows or shrinks a potential pointer to a map element may become a dangling pointer pointing into nowhere (uninitialised memory). The problem here is not "confusion of the user" but that it would break a major design element of Go: No dangling pointers.

    If a slice runs out of capacity a new, larger backing array is created and the old backing array is copied into the new; and the old backing array remains existing. Thus any pointers obtained from the "ungrown" slice pointing into the old backing array are still valid pointers to valid memory.

    If you have a slice still pointing to the old backing array (e.g. because you made a copy of the slice before growing the slice beyond its capacity) you still access the old backing array. This has less to do with pointers of slice elements, but slices being views into arrays and the arrays being copied during slice growth.

    Note that there is no "reducing the backing array of a slice" during slice shrinkage.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?