为什么不通过方法对结构进行更改仍然存在?
问题描述:
我试图理解为什么如预期下面的测试代码是不工作:为什么不通过方法对结构进行更改仍然存在?
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
显然修改...然后它不是。
有人知道可能是什么问题?
答
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"
}
输出
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
通过引用传递,而发生的任何突变是原始对象上进行突变。