首页  >  文章  >  后端开发  >  为什么 Go 中无法通过指针接收器方法修改简单类型值?

为什么 Go 中无法通过指针接收器方法修改简单类型值?

Barbara Streisand
Barbara Streisand原创
2024-11-19 01:12:02268浏览

Why Can't I Modify a Simple Type Value Through a Pointer Receiver Method 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 // Attempt to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Printf("%v\n", fi) // Prints <nil>, not the expected 5
}

为什么指针 fi在 main() 中声明的值不会更改为地址tmp?

说明

当您在 Go 中调用函数或方法时,所有参数(包括接收者)都会作为副本传递。这意味着您无法在函数/方法中修改原始指针值。

在上面的示例中,FromString 方法中的 fi 是 main() 中声明的指针的副本。当您将 fi 分配给 tmp 的地址时,您只是更改了副本的值。原始指针保持不变。

解决方案

此问题常见的解决方案有以下三种:

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 = new(FooInt) // Ensure non-nil receiver
    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() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}

以上是为什么 Go 中无法通过指针接收器方法修改简单类型值?的详细内容。更多信息请关注PHP中文网其他相关文章!

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