您好,匿名用户

Go - 方法接收者类型为 T 与 *T的区别

0 投票
自定义类型方法如下
type cInt []int

func (c cInt) appendV(v int) {
        c = append(c,v)
}

func (c *cInt) appendP(v int)  {
        *c = append(*c,v)
}
测试使用数据
  c := cInt{2,3}
  c.appendV(4)
  c.appendV(5)
  c.appendV(6)
  fmt.Printf("after appendV :%v \n",c)

  c.appendP(9)
  c.appendP(10)
  c.appendP(11)
  fmt.Printf("after appendP :%v \n",c)
测试结果如下
-----------------------------
after appendV :[2 3] 
after appendP :[2 3 9 10 11] 

自己理解的产生原因:

把实参传递给 类型T : 相当于把Slice指向的底层数组的首地址传给虚参
所以在方法内执行c = append(c, v)的时候 分配新的空间,复制c的内容到这个空间中,再添加v,最会把这个新的slice 地址赋值给 c, 而c是局部的变量,出了这个函数之后要被回收,随机这个新的slice 也就被回收,所以append的时候不能添加.

把实参传递给 类型*T : 相当于把指向Slice的变量的地址传给虚参
所以在方法内执行c = append(c, v)的时候 分配新的空间,复制c的内容到这个空间中,再添加v,最会把这个新的slice 地址赋值给 c, 相当于把外部变量的指向这个新的Slice

另一个和Slice,Array 相关的内容
type cInt []int

func (c cInt) zeroValue() {
        for i := range c {
                c[i] = 0
        }
}

func main() {
        fmt.Printf("-------------------\n")
        v := cInt{1,2,3,4,5,6}
        fmt.Printf("v:%v \n",v)
        v.zeroValue()
        fmt.Printf("v:%v \n",v)
        fmt.Printf("-------------------\n")
}
结果为:
-------------------
v:[1 2 3 4 5 6] 
v:[0 0 0 0 0 0] 
-------------------
Other
  1. 上面仅仅是自己的理解,可能存在偏差或者理解错误,望请指正.
  2. 如果你有发现有更多的坑 可以在下面给出,相互学习,感谢在先.
用户头像 提问 5月29日 @ Trundle 中士 (1,407 威望)
分享到:

1个回答

0 投票
 
最佳答案

关于appendV,使用值接收者声明方法,调用时会使用这个值的一个副本来执行
关于appendP,调用使用指针接收者声明的方法时,这个方法会共享调用方法时接收者所指向的值,可以理解为go做了如下调整:

c.appendP(9) -> (&c).appendP(9) 

共享值,故可以改变

用户头像 回复 5月29日 @ Caitlyn 上士 (1,887 威望)
选中 5月16日 @Trundle
提一个问题:

相关问题

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

IT技术交流群 - 随意问
欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...