Golang方法调用值拷贝与引用拷贝

olzhy · 2019-07-02 08:20:29 · 2831 次点击 · 预计阅读时间 11 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-07-02 08:20:29 的文章,其中的信息可能已经有所发展或是发生改变。

1 方法调用采用值拷贝
1.1 array
golang中以array作为参数的方法调用,方法接收的是整个array的值拷贝,所以方法中对array的item重新赋值不起作用。 如以下代码所示,输出为[1, 2, 3]。

  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. func modify(a [3]int) {  
  6.     a[0] = 4  
  7. }  
  8.   
  9. func main() {  
  10.     a := [3]int{123}  
  11.     modify(a)  
  12.     fmt.Println(a)  
  13. }  

1.2 struct
如下代码传参为struct值拷贝,modify方法或modify函数对person的name属性重新赋值不起作用。

  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. type person struct {  
  6.     name string  
  7. }  
  8.   
  9. func (p person) modify() {  
  10.     p.name = "jacky"  
  11. }  
  12.   
  13. func modify(p person) {  
  14.     p.name = "jacky"  
  15. }  
  16.   
  17. func main() {  
  18.     p := person{"larry"}  
  19.     p.modify()  
  20.     // modify(p)  
  21.     fmt.Println(p)  
  22. }  

2 方法调用采用引用拷贝
2.1 slice
slice作为底层的数组引用,方法调用采用的是引用的拷贝。 所以,如下第一段代码,函数的引用拷贝与原始引用指向同一块数组,对slice的item重新赋值是生效的,输出为[4, 2, 3]。
  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. func modify(s []int) {  
  6.     s[0] = 4  
  7. }  
  8.   
  9. func main() {  
  10.     s := []int{123}  
  11.     modify(s)  
  12.     fmt.Println(s)  
  13. }  
但第二段代码,输出结果未变化,仍为[1, 2, 3]。是因为对引用的拷贝重新赋值,并不会更改原始引用。
  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. func modify(s []int) {  
  6.     s = append(s, 4)  
  7. }  
  8.   
  9. func main() {  
  10.     s := []int{123}  
  11.     modify(s)  
  12.     fmt.Println(s)  
  13. }  
所以对slice进行append操作,需要将其作为返回值返回,如以下代码所示,输出为[1 2 3 4]。
  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. func modify(s []int) []int {  
  6.     s = append(s, 4)  
  7.     return s  
  8. }  
  9.   
  10. func main() {  
  11.     s := []int{123}  
  12.     s = modify(s)  
  13.     fmt.Println(s)  
  14. }  

2.2 struct pointer
若想改变struct的属性值,传参采用struct pointer。
  1. package main  
  2.   
  3. import "fmt"  
  4.   
  5. type person struct {  
  6.     name string  
  7. }  
  8.   
  9. func (p person) modify() {  
  10.     p.name = "jacky"  
  11. }  
  12.   
  13. func modify(p person) {  
  14.     p.name = "jacky"  
  15. }  
  16.   
  17. func main() {  
  18.     p := &person{"larry"}  
  19.     p.modify()  
  20.     // modify(p)  
  21.     fmt.Println(p)  
  22. }  


原文地址:https://leileiluoluo.com/posts/golang-method-calling-value-copy-or-reference-copy.html


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2831 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传