golang函数传参方式总结

前端之家收集整理的这篇文章主要介绍了golang函数传参方式总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

先上结论

golang的所有内置类型作为函数参数传递都是传值的方式(没有传递引用一说),需要注意的是:数组、slice和map作为函数参数时也是传值,但是如果对结构内元素进行的修改修改的是原数据。如果是对其进行整体赋值,则不会修改原数据,相当于拷贝出一个新的临时变量。要想无论什么情况都修改原数据,可以通过传递指针参数实现。

来段实例代码

  1. package main
  2.  
  3. import (
  4. "bytes"
  5. "fmt"
  6. "strings"
  7. )
  8.  
  9. func f_1(a int) {
  10. a = 2
  11. }
  12.  
  13. func f_1_1(a *int) {
  14. *a = 2
  15. }
  16.  
  17. func f_2(s string) {
  18. s = "cba"
  19. }
  20.  
  21. func f_2_1(s *string) {
  22. *s = "cba"
  23. }
  24.  
  25. func f_3(v []string) {
  26. v[0] = "haha"
  27. }
  28.  
  29. func f_3_1(v []string) {
  30. v = nil
  31. }
  32.  
  33. func f_3_2(v *[]string) {
  34. *v = nil
  35. }
  36.  
  37. func f_4(m map[int]int) {
  38. m[1] = 3
  39. m[3] = 1
  40. }
  41.  
  42. func f_4_1(m map[int]int) {
  43. m = nil
  44. }
  45.  
  46. func f_4_2(m *map[int]int) {
  47. *m = nil
  48. }
  49.  
  50. func f_5(b []byte) {
  51. b[0] = 0x40
  52. }
  53.  
  54. func f_5_1(b []byte) {
  55. b = bytes.Replace(b,[]byte("1"),[]byte("a"),-1)
  56. }
  57.  
  58. func f_5_2(b *[]byte) {
  59. *b = bytes.Replace(*b,-1)
  60. }
  61.  
  62. type why struct {
  63. s []string
  64. }
  65.  
  66. func (ss why) SetV(s []string) {
  67. ss.s = s
  68. }
  69.  
  70. func (ss *why) SetP(s []string) {
  71. ss.s = s
  72. }
  73.  
  74. func (ss why) String() string {
  75. return strings.Join(ss.s,",")
  76. }
  77.  
  78. func main() {
  79. a := 1
  80. s := "abc"
  81. v := []string{"sd","aa"}
  82. m := map[int]int{1: 1,2: 2,3: 3}
  83. f_1(a)
  84. f_2(s)
  85. f_3(v)
  86. f_4(m)
  87. fmt.Printf("%d,%s,%v,%v\n",a,s,v,m)
  88. f_3_1(v)
  89. f_4_1(m)
  90. fmt.Printf("%d,m)
  91. f_1_1(&a)
  92. f_2_1(&s)
  93. f_3_2(&v)
  94. f_4_2(&m)
  95. fmt.Printf("%d,m)
  96. b := []byte("12145178")
  97. f_5(b)
  98. fmt.Printf("%s\n",b)
  99. f_5_1(b)
  100. fmt.Printf("%s\n",b)
  101. f_5_2(&b)
  102. fmt.Printf("%s\n",b)
  103. ss := &why{}
  104. ss.SetV([]string{"abc","efg"})
  105. fmt.Println(ss)
  106. ss.SetP([]string{"abc","efg"})
  107. fmt.Println(ss)
  108. }

输出如下

  1. 1,abc,[haha aa],map[1:3 2:2 3:1] slicemap值传递是可以修改原数据的,但基本数据类型不行
  2. 1,map[1:3 2:2 3:1] 整体赋值不会修改原数据,值得注意的是map是无序的
  3. 2,cba,[],map[] 传递指针始终会修改原数据
  4. @2145178 同上
  5. @2145178 使用bytes.Replace实际上还是赋值,所以不会修改原数据
  6. @2a45a78 使用指针传参就可以了
  7. 类的成员函数定义为传值的方式,不会修改原数据(原数据为空)
  8. abc,efg 类的成员函数定义为传指针的方式,可以修改原成员变量
  9.  
  10. 成功: 进程退出代码 0.

现在弄明白了吗~

猜你在找的Go相关文章