2 回答

TA贡献1844条经验 获得超8个赞
所有参数(包括接收者)都是函数/方法内部的副本。您只能修改副本。
这也适用于指针:接收器值(fi指针)是副本,因此您不能修改原始指针,只能修改副本。
通常接收者是一个非nil指针,而你修改了指向的值——这会导致原来的指向值改变。
在您的情况下,您要么必须返回指针并分配返回值:
func (fi *FooInt) FromString(i string) *FooInt {
num, _ := strconv.Atoi(i)
tmp := FooInt(num)
return &tmp
}
func main() {
var fi *FooInt
fi = fi.FromString("5")
fmt.Printf("%v %v\n", fi, *fi)
}
这将输出(在Go Playground上尝试):
0xc0000b4020 5
或者将非nil指针传递给您要更改的内容,在您的情况下,它将是类型**FooInt
func (fi *FooInt) FromString(i string, p **FooInt) {
num, _ := strconv.Atoi(i)
tmp := FooInt(num)
*p = &tmp
}
func main() {
var fi *FooInt
fi.FromString("5", &fi)
fmt.Printf("%v %v\n", fi, *fi)
}
这输出相同。在Go Playground上尝试一下。
但最简单的方法是确保接收器不是nil,因此可以简单地修改指向的值:
func (fi *FooInt) FromString(i string) {
num, _ := strconv.Atoi(i)
*fi = FooInt(num)
}
func main() {
var fi *FooInt
fi = new(FooInt)
fi.FromString("5")
fmt.Printf("%v %v\n", fi, *fi)
}
输出是一样的。在Go Playground上试试这个。

TA贡献1796条经验 获得超4个赞
语法:
func (fi *FooInt) FromString(i string) {
// ...
}
部分是语法糖:
func FromString(fi *fooInt, i string) {
// ...
}
也就是fi这里的参数是一个普通的局部变量。如果分配给它,则替换调用者提供的指针值,而不是通过调用者提供的指针值写入。因此,您需要使用:
*fi = FooInt(num)
在函数体中。但是,现在调用者必须传递一个非零指针:
var fi FooInt
fi.FromString("5")
例如。
这是一个完整的示例,包括一个可以调用FromString函数并传递显式指针的方法。
(我说部分语法糖,因为它定义FromString为接收器函数或方法,只能使用这种语法来完成。所以语法是必需的——它不是其他语法的替代品,正如人们有时在使用短语“语法”时所说的那样糖”。)
- 2 回答
- 0 关注
- 153 浏览
添加回答
举报