Вот фундаментальное понимание, которого вам не хватает: когда структура передается функции в качестве указателя, функция может изменить исходную структуру, потому что она имеет указатель на нее.Однако, когда структура передается функции через ее значение, тогда фактически создается НОВАЯ копия структуры только для этого вызова функции, и любые изменения этой новой копии структуры не влияют на исходную структуру.
Вы можете доказать, что так оно и работает, распечатав фактические адреса рассматриваемых структур:
package main
import "fmt"
type T struct { Val string }
func (t T) SetVal( s string ) {
fmt.Printf("Address of copy is %p\n", &t);
}
func (t *T) SetVal2( s string ) {
fmt.Printf("Pointer argument is %p\n", t);
}
func main() {
v := T{"abc"}
fmt.Printf("Address of v is %p\n", &v);
v.SetVal("pdq")
v.SetVal2("xyz")
}
Приведенный выше код приводит к таким выводам, когда я запускаю его на игровой площадке Go:
Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
Обратите внимание, как распечатаны первый и третий указатели, что означает, что они имеют одинаковую структуру.Но второй указатель отличается тем, что он является копией.
Кстати, это похоже на то, как работает структура C / параметры функции.