Почему адрес памяти изменяется после назначения среза - PullRequest
0 голосов
/ 11 ноября 2019

Есть две проблемы, которые я не понимаю.
Во-первых, одна переменная слайса назначается другой переменной, и обнаруживается, что адрес новой переменной не совпадает с адресом переменной. Насколько я понимаю, срез разделяет память, и их адреса совпадают в соответствии с принципом.

Второй - тогда, когда переменная среза имеет недостаточную емкость, адрес памяти не изменяется после операции добавления. Он должен меняться в соответствии с принципом, потому что адрес памяти будет выделен заново при недостаточной емкости.

Буду признателен за ваши комментарии.

var a = []int{1,2,3}
fmt.Printf("%p\n",&a)
b:=a
fmt.Printf("%p\n",&b) 1)、the first question
b=append(b,0)
fmt.Printf("%p\n",&b) 2)、the second question
fmt.Println(a)
fmt.Println(b)

Результат выполнения:

0xc04204c3a0
0xc04204c3e0
0xc04204c3e0
[1 2 3]
[1 2 3 0]

Ответы [ 2 ]

4 голосов
/ 11 ноября 2019

Значение среза содержит указатель на базовый массив, длину и емкость. См. Go Slices: использование и внутреннее устройство для деталей.

Вот некоторые комментарии к коду в вопросе:

var a = []int{1, 2, 3}

// Print address of variable a
fmt.Printf("%p\n", &a)

b := a

// Print address of variable b. The variable a and b
// have different addresses.
fmt.Printf("%p\n", &b)

b = append(b, 0)

// Print address of variable b. Append did not change
// the address of the variable b.
fmt.Printf("%p\n", &b)

Напечатайте адрес первого элемента среза, чтобы получить ожидаемые результаты.

var a = []int{1, 2, 3}

// Print address of a's first element
fmt.Printf("%p\n", &a[0])

b := a

// Print address of b's first element. This prints
// same value as previous because a and b share a backing
// array.
fmt.Printf("%p\n", &b[0])

b = append(b, 0)

// Print address of b's first element. This prints a 
// different value from previous because append allocated
// a new backing array.
fmt.Printf("%p\n", &b[0])
1 голос
/ 11 ноября 2019
// create a new slice struct which contains length, capacity and the underlying array. 
// len(a)=3, cap(a)=3
var a = []int{1,2,3}

// `&a` means the pointer to slice struct
fmt.Printf("%p\n",&a)

// `b` is another newly created variable of slice struct, so `&b` differs from `&a`, 
// but they share the same underlying array.
// len(b)=3, cap(b)=3
b := a

// the underlying array of `b` has been extended, and been newly allocated.
// but the pointer of `b` remains.
// len(b)=4, cap(b)=6
b = append(b, 0)

Надеюсь, что эти комментарии помогут вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...