首先,go中的赋值,都是值传递c++
a := 1
b := a
x := Struct{}
y := x
复制代码
他们都是在内存中有独立空间的,也就是copy
的过程,因此这里对y的某个属性的改动,并不会影响xgolang
那么咱们要让两个变量指向同一个内存怎么办呢,可使用引用类型:数组
y := &x
复制代码
这时候,y的类型是*Struct
,这时候咱们能够对y进行修改,修改完以后,x也会发现变化,由于y如今是一个引用类型,他指向的是x结构体所在的内存bash
咱们能够经过:函数
y.variable = xxx
复制代码
来直接调用引用类型的结构体赋值,可是要注意的是,这是go的语法糖,他只是帮助咱们简化了经过指针来获取实际内存的过程,完整的写法应该是这样的:ui
(*y).variable = xxx
复制代码
*y
是对指针的反引用,能够理解为*y == x
。spa
为何设计这个语法糖呢,是由于在go里面咱们是没法直接操做指针,像c++中直接对内存地址进行计算进而获得其余内存地址的运算,在go里面是默认不支持的设计
print(y) // 获得相似0x8123这样的内存地址数据
// 理论上能够获得一个新的内存地址,可是在go里默认是不支持的
newAddr := y + 4
复制代码
由于没法直接操做地址,因此go就提供语法糖,让咱们在使用引用类型进行操做的时候,默认就是对引用所指向的内存地址进行操做。指针
注意咱们是能够对引用类型直接赋值的,可是赋值的类型也必须是引用类型code
y = &Struct{} // 这样是能够的,可是不能是y = Struct{}
a := 1
b := &a
b = 2 // 这是不行的,由于b的类型是 *int
复制代码
可以经过make()
函数建立的都是引用类型,好比slice
和map
,slice
虽然看起来像数组,可是他实际上是一个指向数组内存空间的一个指针类型
type Slice struct {
point Point // 内存地址
len int
cap int
}
复制代码
因此咱们在执行:
a := []int
b = a
复制代码
会发现,好像b和a指向的是同一个数组,事实确实如此。go中全部的赋值都是值传递,而slice的赋值,也是对slice对象的一次拷贝,也就是说a和b是不一样的slice对象,可是他们指向同一个数组
同理map也是如此,就很少讲来。