2013-05-14 219 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通过引用传递,而发生的任何突变是原始对象上进行突变。

相关问题