<strong>1 方法调用采用值拷贝</strong>
<br />
<strong>1.1 array</strong>
<br />
golang中以array作为参数的方法调用,方法接收的是整个array的值拷贝,所以方法中对array的item重新赋值不起作用。
如以下代码所示,输出为[1, 2, 3]。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>func modify(a [<span class="number">3</span><span>]</span><span class="keyword">int</span><span>) { </span></span></li><li class=""><span> a[<span class="number">0</span><span>] = </span><span class="number">4</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func main() { </span></li><li class=""><span> a := [<span class="number">3</span><span>]</span><span class="keyword">int</span><span>{</span><span class="number">1</span><span>, </span><span class="number">2</span><span>, </span><span class="number">3</span><span>} </span></span></li><li class="alt"><span> modify(a) </span></li><li class=""><span> fmt.Println(a) </span></li><li class="alt"><span>} </span></li></ol></div>
<br />
<strong>1.2 struct</strong>
<br />
如下代码传参为struct值拷贝,modify方法或modify函数对person的name属性重新赋值不起作用。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>type person struct { </span></li><li class=""><span> name string </span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func (p person) modify() { </span></li><li class=""><span> p.name = <span class="string">"jacky"</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func modify(p person) { </span></li><li class=""><span> p.name = <span class="string">"jacky"</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func main() { </span></li><li class=""><span> p := person{<span class="string">"larry"</span><span>} </span></span></li><li class="alt"><span> p.modify() </span></li><li class=""><span> <span class="comment">// modify(p)</span><span> </span></span></li><li class="alt"><span> fmt.Println(p) </span></li><li class=""><span>} </span></li></ol></div>
<br />
<strong>2 方法调用采用引用拷贝</strong>
<br />
<strong>2.1 slice</strong>
<br />
slice作为底层的数组引用,方法调用采用的是引用的拷贝。
所以,如下第一段代码,函数的引用拷贝与原始引用指向同一块数组,对slice的item重新赋值是生效的,输出为[4, 2, 3]。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>func modify(s []<span class="keyword">int</span><span>) { </span></span></li><li class=""><span> s[<span class="number">0</span><span>] = </span><span class="number">4</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func main() { </span></li><li class=""><span> s := []<span class="keyword">int</span><span>{</span><span class="number">1</span><span>, </span><span class="number">2</span><span>, </span><span class="number">3</span><span>} </span></span></li><li class="alt"><span> modify(s) </span></li><li class=""><span> fmt.Println(s) </span></li><li class="alt"><span>} </span></li></ol></div>
但第二段代码,输出结果未变化,仍为[1, 2, 3]。是因为对引用的拷贝重新赋值,并不会更改原始引用。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>func modify(s []<span class="keyword">int</span><span>) { </span></span></li><li class=""><span> s = append(s, <span class="number">4</span><span>) </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func main() { </span></li><li class=""><span> s := []<span class="keyword">int</span><span>{</span><span class="number">1</span><span>, </span><span class="number">2</span><span>, </span><span class="number">3</span><span>} </span></span></li><li class="alt"><span> modify(s) </span></li><li class=""><span> fmt.Println(s) </span></li><li class="alt"><span>} </span></li></ol></div>
所以对slice进行append操作,需要将其作为返回值返回,如以下代码所示,输出为[1 2 3 4]。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>func modify(s []<span class="keyword">int</span><span>) []</span><span class="keyword">int</span><span> { </span></span></li><li class=""><span> s = append(s, <span class="number">4</span><span>) </span></span></li><li class="alt"><span> <span class="keyword">return</span><span> s </span></span></li><li class=""><span>} </span></li><li class="alt"><span> </span></li><li class=""><span>func main() { </span></li><li class="alt"><span> s := []<span class="keyword">int</span><span>{</span><span class="number">1</span><span>, </span><span class="number">2</span><span>, </span><span class="number">3</span><span>} </span></span></li><li class=""><span> s = modify(s) </span></li><li class="alt"><span> fmt.Println(s) </span></li><li class=""><span>} </span></li></ol></div>
<br />
<strong>2.2 struct pointer</strong>
<br />
若想改变struct的属性值,传参采用struct pointer。
<div class="dp-highlighter"><div class="bar"></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> main </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">import</span><span> </span><span class="string">"fmt"</span><span> </span></span></li><li class=""><span> </span></li><li class="alt"><span>type person struct { </span></li><li class=""><span> name string </span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func (p *person) modify() { </span></li><li class=""><span> p.name = <span class="string">"jacky"</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func modify(p *person) { </span></li><li class=""><span> p.name = <span class="string">"jacky"</span><span> </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span>func main() { </span></li><li class=""><span> p := &person{<span class="string">"larry"</span><span>} </span></span></li><li class="alt"><span> p.modify() </span></li><li class=""><span> <span class="comment">// modify(p)</span><span> </span></span></li><li class="alt"><span> fmt.Println(p) </span></li><li class=""><span>} </span></li></ol></div>
<br />
原文地址:https://leileiluoluo.com/posts/golang-method-calling-value-copy-or-reference-copy.html
有疑问加站长微信联系(非本文作者))