首页  >  文章  >  后端开发  >  为什么我不能在 Go 中使用指针接收器修改简单类型的值?

为什么我不能在 Go 中使用指针接收器修改简单类型的值?

Barbara Streisand
Barbara Streisand原创
2024-11-16 06:53:03233浏览

Why Can't I Modify a Simple Type's Value Using a Pointer Receiver in Go?

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

在 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) // Prints <nil>
}

在这里,您期望函数 FromString将 fi 的值设置为 5。但它打印 ,表示 nil指针。

理解行为

在 Go 中,函数/方法参数(包括接收者)是原始值的副本。因此,函数内的修改只会影响副本。

即使对于指针,接收者也是原始指针的副本,而不是实际的指针本身。因此,对接收者的值进行的修改不会影响原始指针。

解决方案

要解决此问题,有几个选项:

  1. 返回修改后的内容指针:

    • 修改函数,返回修改后的指针,并赋值给原来的指针。
    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) // Prints 0xc0000b4020 5
    }
  2. 传递一个指针进行修改:

    • 传递指向函数的所需类型的非零指针,并修改其值。
    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) // Prints 0xc0000b4020 5
    }
  3. 确保非零接收者:

    • 在调用方法之前将接收者初始化为非零值,因此指向的值可以
    func (fi *FooInt) FromString(i string) {
        num, _ := strconv.Atoi(i)
        *fi = FooInt(num)
    }
    
    func main() {
        fi := new(FooInt) // Initialize to non-nil
        fi.FromString("5")
        fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }

通过采用其中一种解决方案,您可以使用指针接收器有效地修改简单类型的值。

以上是为什么我不能在 Go 中使用指针接收器修改简单类型的值?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn