drq231358 2018-03-22 09:37
浏览 32
已采纳

附加到切片的元素的地址

I want to create element, add it to the slice and change it by its address. I expect that the change of the element from the outside will change also a slice. But after the addition, a new slice is created. I use serialization, so the use of an slice of addresses is not suitable, also the addition of elements occurs in different goroutines, so accessing the last added element is also not suitable.

package main

import (
    "fmt"
)

func main() {
    var a []int
    b := 1
    fmt.Println("old addr:", &b)
    // old addr: 0x10414020
    a = append(a, b)
    fmt.Println("new addr:", &a[0])
    // new addr: 0x10414028
}

play golang example

  • 写回答

3条回答 默认 最新

  • douhao123457 2018-03-22 10:10
    关注

    This is not an issue of append() creating a new slice header and backing array.

    This is an issue of you appending b to the slice a, a copy of the value of the b variable will be appended. You append a value, not a variable! And by the way, appending (or assigning) makes a copy of the value being appended (or assigned).

    Note that the address of b and a[0] will also be different if you do not call append() but instead preallocate the slice and simply assign b to a[0]:

    var a = make([]int, 1)
    b := 1
    fmt.Println("old addr:", &b)
    // old addr: 0x10414024
    a[0] = b
    fmt.Println("new addr:", &a[0])
    // new addr: 0x10414020
    

    Try it on the Go Playground.

    The reason for this is because the variable b and a are distinct variables; or more precisely the variable b and a's backing array reserving the memory for its elements (including the memory space for a[0]), so their addresses cannot be the same!

    You cannot create a variable placed to the same memory location of another variable. To achieve this "effect", you have pointers at your hand. You have to create a pointer variable, which you can set to point to another, existing variable. And by accessing and modifying the pointed value, effectively you are accessing and modifying the variable whose address you stored in the pointer.

    If you want to store "something" in the a slice through which you can access and modify the "outsider" b variable, the easiest is to store its address, which will be of type *int.

    Example:

    var a []*int
    b := 1
    fmt.Println("b's addr:", &b)
    a = append(a, &b)
    fmt.Println("addr in a[0]:", a[0])
    
    // Modify b via a[0]:
    *a[0] = *a[0] + 1
    fmt.Println("b:", b)
    

    Output (try it on the Go Playground):

    b's addr: 0x10414020
    addr in a[0]: 0x10414020
    b: 2
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?