关于go很多是说map/chan/slice是reference type的,即传引用,也即在赋值的时候是传递的引用,即传递的内存地址。如果是赋值,就是给这个内存地址加一个新的变量名而已。如果其中一个变量对内存里面的值进行了修改,其余的变量也会生效。
现在通过代码验证下:
```go
func main() {
a := []int{1,2,3}
fmt.Printf("a addr: %p\n", &a) //a addr: 0xc00011a000
b := a
fmt.Printf("b addr: %p\n", &b) //b addr: 0xc00011a020
b[1] = 10
fmt.Println(a) //[1 10 3]
}
```
咦??切片a跟切片b的地址竟然是不一样的!!但是如果其中一个变量对切片进行了修改,那么另外一个切片也发生了修改,这个修改当然是符合我们认知的,也是预期的。但是为什么两个切片的地址是不一样的呢?既然两个切片地址是不一样的,那说明在两个不同的内存空间存储了不同的数据,那为什么一个内存中的数据变了,另一个内存中的数据也跟着变了呢?
<a href="/user/colinrs" title="@colinrs">@colinrs</a> 我想表达的意思就是,切片是“类型引用”的,也即,“如果把它赋值给一个新的变量,这个新的变量跟原来的变量是共享一个地址空间的”。但是通过上面打印,发现这两个变量的地址空间并不是一样的。
但是通过@focuseonline的回答,我理解了,其实这两个变量存的是两个指针,两个这打印出来的是这两个指针的地址。其实这两个指针指向的是同一个切片的地址。
#4
更多评论
a := [3]int{1, 2, 3}
fmt.Printf("a addr: %p\n", &a) //a addr: 0xc00011a000
b := a
fmt.Printf("b addr: %p\n", &b) //b addr: 0xc00011a020
b[1] = 10
fmt.Println(a) //[1 2 3]
试试这个
#2