Допустим, у меня есть структура с параметром среза, как показано ниже, и я создаю ее и заполняю ее некоторыми значениями:
type s struct {
sl []float32
}
func NewS() *s {
return &s{
sl: make([]float32, 3),
}
}
func main() {
a := NewS()
a.sl[0] = 1
a.sl[1] = 2
a.sl[2] = 3
b := NewS()
// Code here
}
Я хочу, чтобы b
имел sl
с теми же значениями, что и a.sl
, и, в частности, я хотел бы понять, как это сделать разными способами:
- Где весь
b
указывает на весьa
(чтобы, если бы в структуре были другие параметры, все они совпадали бы) - Где
b.sl
будет указывать наa.sl
- Как глубокая копия, где нет указателей (и выполняется не путем итерации по срезу, а таким образом, который в идеале повторяется независимо от типа)
Далее следует то, что я пробовал и нашел до сих пор.
b = a
fmt.Printf("a: %p\n", &a)
fmt.Printf("b: %p\n", &b)
fmt.Printf("a.sl: %p\n", &a.sl)
fmt.Printf("b.sl: %p\n", &b.sl)
Который выводит разные адреса памяти для структур, но одни и те же адреса памяти для срезов. Почему это? Почему бы и адреса структур не быть одинаковыми, если a просто указывает на b?
a: 0xc00000e030
b: 0xc00000e038
a.sl: 0xc000054040
b.sl: 0xc000054040
Затем я попробовал:
b.sl = a.sl
// ...
Который выводит все разные адреса памяти. Понятно, что адреса a
и b
разные, но почему b.sl
не указывает на адрес a.sl
?
a: 0xc00000e028
b: 0xc00000e030
a.sl: 0xc00000c030
b.sl: 0xc00000c048
И, наконец, я попробовал:
copy(b.sl, a.sl)
// ...
Что выводит аналогично приведенному выше. Это единственный результат, который я ожидал, так как я ожидал, что это сделает глубокую копию.
a: 0xc0000b8018
b: 0xc0000b8020
a.sl: 0xc0000ae018
b.sl: 0xc0000ae030
Не могли бы вы помочь мне понять, что происходит в этих трех случаях, и другие способы достижения желаемых результатов и выполнения различных типов копий?