如何通过 Go 中的指针接收器方法修改简单类型的值?

我想有一个基于基本类型的自定义类型,并能够通过调用指针接收器来设置它的值。


当我运行以下程序时:


package main


import (

    "fmt"

    "strconv"

)


type FooInt int

func (fi *FooInt) FromString(i string) {

    num, _ := strconv.Atoi(i)

    tmp := FooInt(num)

    fi = &tmp

}


func main() {

    var fi *FooInt

    fi.FromString("5")

    fmt.Printf("%v\n", fi)

}

我收到<nil>。为什么声明的指针不将main()其值更改为的地址tmp?


SMILET
浏览 154回答 2
2回答

婷婷同学_

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

慕的地8271018

语法:func (fi *FooInt) FromString(i string) {&nbsp; &nbsp; // ...}部分是语法糖:func FromString(fi *fooInt, i string) {&nbsp; &nbsp; // ...}也就是fi这里的参数是一个普通的局部变量。如果分配给它,则替换调用者提供的指针值,而不是通过调用者提供的指针值写入。因此,您需要使用:&nbsp; &nbsp; *fi = FooInt(num)在函数体中。但是,现在调用者必须传递一个非零指针:var fi FooIntfi.FromString("5")例如。这是一个完整的示例,包括一个可以调用FromString函数并传递显式指针的方法。(我说部分语法糖,因为它定义FromString为接收器函数或方法,只能使用这种语法来完成。所以语法是必需的——它不是其他语法的替代品,正如人们有时在使用短语“语法”时所说的那样糖”。)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go