先上结论
golang的所有内置类型作为函数参数传递都是传值的方式(没有传递引用一说),需要注意的是:数组、slice和map作为函数参数时也是传值,但是如果对结构内元素进行的修改,修改的是原数据。如果是对其进行整体赋值,则不会修改原数据,相当于拷贝出一个新的临时变量。要想无论什么情况都修改原数据,可以通过传递指针参数实现。
来段实例代码
package main import ( "bytes" "fmt" "strings" ) func f_1(a int) { a = 2 } func f_1_1(a *int) { *a = 2 } func f_2(s string) { s = "cba" } func f_2_1(s *string) { *s = "cba" } func f_3(v []string) { v[0] = "haha" } func f_3_1(v []string) { v = nil } func f_3_2(v *[]string) { *v = nil } func f_4(m map[int]int) { m[1] = 3 m[3] = 1 } func f_4_1(m map[int]int) { m = nil } func f_4_2(m *map[int]int) { *m = nil } func f_5(b []byte) { b[0] = 0x40 } func f_5_1(b []byte) { b = bytes.Replace(b,[]byte("1"),[]byte("a"),-1) } func f_5_2(b *[]byte) { *b = bytes.Replace(*b,-1) } type why struct { s []string } func (ss why) SetV(s []string) { ss.s = s } func (ss *why) SetP(s []string) { ss.s = s } func (ss why) String() string { return strings.Join(ss.s,",") } func main() { a := 1 s := "abc" v := []string{"sd","aa"} m := map[int]int{1: 1,2: 2,3: 3} f_1(a) f_2(s) f_3(v) f_4(m) fmt.Printf("%d,%s,%v,%v\n",a,s,v,m) f_3_1(v) f_4_1(m) fmt.Printf("%d,m) f_1_1(&a) f_2_1(&s) f_3_2(&v) f_4_2(&m) fmt.Printf("%d,m) b := []byte("12145178") f_5(b) fmt.Printf("%s\n",b) f_5_1(b) fmt.Printf("%s\n",b) f_5_2(&b) fmt.Printf("%s\n",b) ss := &why{} ss.SetV([]string{"abc","efg"}) fmt.Println(ss) ss.SetP([]string{"abc","efg"}) fmt.Println(ss) }
输出如下
1,abc,[haha aa],map[1:3 2:2 3:1] slice和map值传递是可以修改原数据的,但基本数据类型不行 1,map[1:3 2:2 3:1] 整体赋值不会修改原数据,值得注意的是map是无序的 2,cba,[],map[] 传递指针始终会修改原数据 @2145178 同上 @2145178 使用bytes.Replace实际上还是赋值,所以不会修改原数据 @2a45a78 使用指针传参就可以了 类的成员函数定义为传值的方式,不会修改原数据(原数据为空) abc,efg 类的成员函数定义为传指针的方式,可以修改原成员变量 成功: 进程退出代码 0.
现在弄明白了吗~