https://www.cnblogs.com/wang_yb/p/12126884.html
leetcode:322
Golang本质是传值,即形参会自动在方法体内新开辟一段内存空间,所有的操作都是在这块新的内存空间去操作的,除了该方法的作用域后该内存空间被回收,而不会影响到你想改变的那个变量。
1.对于普通类型(int, string 等等), 就是 传值 调用, 函数内对参数的修改, 不影响外面的变量
2.对于 struct 指针, slice 和 map 类型, 函数内对参数的修改之所以能影响外面, 是因为参数和外面的变量指向了同一块数据的地址
3.对于 struct 指针, slice 和 map 类型, 函数的参数和外面的变量的地址是不一样的, 所以本质上还是 传值 调用
4.slice 的 append 操作会改变 slice 指针的地址, 这个非常重要!!! 我曾经写了一个基于 slice 的排序算法在这个上面吃了大亏, 调研很久才发现原因…
1.无法修改a
func main() {
a := 10
change(a)
fmt.Println(a)
}
func change(a int) {
a = 18
}
2.修改成功
func main() {
a := []int{1,2}
change(a)
fmt.Println(a)
}
func change(b []int) {
b[0] = 3
}
3.append失败
func main() {
a := make([]int,2,2)
a[0] = 1
a[1] = 2
change(a)
fmt.Println(a) // a = [1,2]
}
func change(b []int) {
b = append(b,3) // b = [1,2,3]
}
4..append成功,参考heap.Push -> h.Push
func main() {
a := make([]int,2,2)
a[0] = 1
a[1] = 2
change(a)
fmt.Println(a)
}
func change(b *[]int) {
*b = append(*b,3)
}
方法:
func (r ReceiverType) funcName(parameters) (results)
当调用method时,会将receiver作为函数的第一个参数:
funcName(r, parameters);
所以,receiver是值类型还是指针类型要看method的作用。如果要修改对象的值,就需要传递对象的指针。
指针作为Receiver会对实例对象的内容发生操作,而普通类型作为Receiver仅仅是以副本作为操作对象,并不对原实例对象发生操作。
func (a *Ingeger) Add(b Integer) {
*a += b
}
func main() {
var a Integer = 1
a.Add(3)
fmt.Println("a =", a) // a = 4
}
如果Add方法不使用指针,则a返回的结果不变,这是因为Go语言函数的参数也是基于值传递。
注意:当方法的接受者是指针时,即使 使用值类型调用,方法内部也是对指针的操作。