Function 为什么我通过的结构没有改变
我通过引用将结构传递给函数 我希望如果我在函数内部定义并更改结构,我可以在函数外部获得新值 但事实并非如此 有人能解释为什么吗Function 为什么我通过的结构没有改变,function,pointers,go,Function,Pointers,Go,我通过引用将结构传递给函数 我希望如果我在函数内部定义并更改结构,我可以在函数外部获得新值 但事实并非如此 有人能解释为什么吗 package main import "fmt" func intbyRef(i *int) { *i = 10 } type ttt struct { a int } func change(t *ttt) { var p ttt = ttt{7} fmt.Println(p) t = &p } func
package main
import "fmt"
func intbyRef(i *int) {
*i = 10
}
type ttt struct {
a int
}
func change(t *ttt) {
var p ttt = ttt{7}
fmt.Println(p)
t = &p
}
func main() {
i := 1
var t *ttt
fmt.Println(i)
fmt.Println(t)
change(t)
intbyRef(&i)
fmt.Println(i)
fmt.Println(t)
}
您可以在这里尝试代码:在我们的代码中,您正在函数更改中创建ttt的新对象,并将其分配给t,t作为参数传递给函数。In-go参数是按值传递的,因此在函数更改结束时,您将值赋给t仅用于函数的范围。为了将更改传播到调用函数,请从更改返回值并将其赋值 已对您的代码进行了更改,请检查游戏地面链接
您不是在函数中更改结构,而是通过将其设置为不同的内存地址来更改值。换句话说,您没有更改存储在
t
引用的地址处的对象,而是更改t
本身的指针值,这不会更改函数外部t
变量的指针值(因为Golang是传递值)
为了实现您想要的功能,代码应该与您为intbyRef
所做的类似,即:
func change(t *ttt) {
var p ttt = ttt{7}
fmt.Println(p)
*t = p
}
但是,这将因零指针解引用而导致恐慌。您的主函数还应该执行您使用int所做的操作:
func main() {
i := 1
// var t *ttt
t := new(ttt)
...
}
完整代码如下(游乐场链接):
此外,您可能希望防止出现nil值和返回错误,尤其是对于包内部的函数。您正在将初始化的指针值传递到
intByRef
并更改取消引用的值
在更改中
传递未初始化的指针值(也称为nil)并为其分配另一个指针
所以你在做两件不同的事情
您应该知道,当您向函数传递指针时,您会传递该指针的副本(指向相同的值)。这就是为什么main
的t
在传递给change
后保持不变的原因。它指向“旧”内存地址
如果要更改传递给函数的ttt
指针的值,可以像在intByRef
中那样执行,但指针必须初始化(也称为分配)。否则你会尝试取消对nil的引用
关于«一般来说,您应该防止出现零值和返回错误。»——请不要!为什么?请考虑不学习这个“引用”的误称。在某些语言中,存在着区别:例如,在Python和PHP中,整数类型的值通过值传递,类类型的对象通过引用传递。相反,在GO中,所有值都是通过值传递的,只是可以显式地将指针传递给值——如果您希望被调用方修改指向的值,或者希望避免复制开销。请考虑阅读和。
package main
import "fmt"
func intbyRef(i *int) {
*i = 10
}
type ttt struct {
a int
}
func change(t *ttt) {
var p ttt = ttt{7}
fmt.Println(p)
// t = &p
*t = p
}
func main() {
i := 1
// var t *ttt
t := new(ttt)
fmt.Println(i)
fmt.Println(t)
change(t)
intbyRef(&i)
fmt.Println(i)
fmt.Println(t)
}
func change(t *ttt) {
var p ttt = ttt{7}
fmt.Println(p)
*t = p
}
func main() {
t := new(ttt)
fmt.Println(t)
change(t)
fmt.Println(t)
}