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)
}