pointers - 如何通过 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
?
这是一个Go 游乐场链接。
解决方案
所有参数(包括接收者)都是函数/方法内部的副本。您只能修改副本。
这也适用于指针:接收器值(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上试试这个。
推荐阅读
- javascript - echarts y轴不按顺序显示数组中的值
- javascript - Libretranslate Javascript 响应访问问题
- redis - 带有 Redis 关闭/断开连接的 NestJS Typeorm 缓存
- sql - INSERT 语句与 FOREIGN KEY 约束冲突 - SQL
- classification - Pycaret:使用 cross_val_predict 堆叠具有“时间序列”错误的模型
- c - 意外的答案
- java - 将行和列坐标转换为 JSON 调试器的插入符号位置
- linux - 如何解决 /bin/bash:权限被拒绝
- wordpress - 如何使用 Weglot 修改我的页面中的翻译
- laravel - 在没有通知的情况下在 Laravel 中发送 geric 通知