2013-05-14 217 views
7

我試圖理解爲什麼如預期下面的測試代碼是不工作:爲什麼不通過方法對結構進行更改仍然存在?

package main 

import (
    "fmt" 
    "strings" 
) 

type Test struct { 
    someStrings []string 
} 

func (this Test) AddString(s string) { 
    this.someStrings = append(this.someStrings, s) 
    this.Count() // will print "1" 
} 

func (this Test) Count() { 
    fmt.Println(len(this.someStrings)) 
} 

func main() { 
    var test Test 
    test.AddString("testing") 
    test.Count() // will print "0" 
} 

這將打印:

"1" 
"0" 

意思就是說someStrings顯然修改...然後它不是。

有人知道可能是什麼問題?

回答

12

AddString方法正在使用值(複製)接收器。修改是針對副本進行的,而不是原始的。指針接收器必須用於改動原始實體:

package main 

import (
     "fmt" 
) 

type Test struct { 
     someStrings []string 
} 

func (t *Test) AddString(s string) { 
     t.someStrings = append(t.someStrings, s) 
     t.Count() // will print "1" 
} 

func (t Test) Count() { 
     fmt.Println(len(t.someStrings)) 
} 

func main() { 
     var test Test 
     test.AddString("testing") 
     test.Count() // will print "0" 
} 

Playground


輸出

1 
1 
1

你的功能對象本身,而不是一個指針到對象上定義。

func (this Test) AddString(s string) { 
    this.someStrings = append(this.someStrings, s) 
    this.Count() // will print "1" 
} 

上面的函數是在具體數據上定義的。這意味着當您調用該函數時,this的值將作爲數據的副本傳入。所以,你做this任何突變副本上進行(在這種情況下,突變改變指針「someStrings」點我們可以重寫上測試的指針定義爲jnml做了同樣的功能:

func (this *Test) AddString(s string) { 
    this.someStrings = append(this.someStrings, s) 
    this.Count() // will print "1" 
} 

正如你可以看到,函數的定義是(this *Test)而不是(this Test)。這意味着變量this通過引用傳遞,而發生的任何突變是原始對象上進行突變。

相關問題