一、定义
在golang中 变量作为函数的参数,其实是拷贝变量的副本传入函数。
在函数修改的是这个副本,而不是原始变量。除非变量是一个指针,原始变量和副本变量都指向同个内存地址,则会互相修改,互相影响。

二、数据类型
(1)值类型包括:
布尔型(bool)
数字类型(包括整型 int 和浮点型 float32、float64)
字符串类型(string)
数组(array)

(2)引用类型包括:
切片(slice)
映射(map)
通道(channel)
指针(pointer)
函数(function)

三、如果参数 是引用类型
引用类型定义 :这些类型的变量存储了一个指向底层数据结构的内存地址,而不是数据本身。与引用类型相关联的是在变量、数组、切片、映射和通道等数据结构上执行的操作,会直接影响底层数据结构,而不是复制数据本身。
例如 参数是map,在函数内修改map变量的内部值(底层数据),原始变量也会跟着修改。虽然参数是原始变量的副本但是他们底层数据指向同个内存地址。
如果在函数内修改 原始变量的副本 则不影响原始变量。

#修改map变量的内部值(底层数据)
data:=map[string]string{"a":"b"}
func t(data map){
  data["a"]="c"
  fmt.Println(data)
}
t(data)
fmt.Println(data)

输出结果:
{"a":"c"}
{"a":"c"}
#修改 原始变量的副本
data:=map[string]string{"a":"b"}
func t(data map){
  data=map[string]string{}
  fmt.Println(data)
}
t(data)
fmt.Println(data)

输出结果:
{}
{"a":"c"}

slice实验 如果参数是slice类型,append数据 底层数据需要扩容,这个时候 原始变量会受到影响吗

func c(s []string) {
    fmt.Printf("s 的内存地址是 %p %d \n", &s, cap(s))
    s = append(s, "c")
    fmt.Printf("s 的内存地址是 %p %d \n", &s, cap(s))
    fmt.Println(s)
}

func TestAppend(t *testing.T) {
    s := make([]string, 1, 30)
    s[0] = "a"
    fmt.Printf("原始s 的内存地址是 %p %d\n", &s, cap(s))
    c(s)
    fmt.Println(s)
}

输出
原始s 的内存地址是 0xc0001b27f8 30
s 的内存地址是 0xc0001b2810 30 
s 的内存地址是 0xc0001b2810 30 
[a c]
[a]

这里有问题,容量充足的情况下,底层数据不需要扩容,都会指向同个内存地址,原始变量应该会受到影响,跟着改变才对的。这里却没有。
只有容量不足的情况下,底层数据会重新申请,并把旧数据复制到新申请的内存上,这个时候修改才不会影响到原始变量。