猿问

为什么我传递的结构没有改变

我通过引用将结构传递给函数。


我期待如果我在函数内部定义和更改结构,我可以获得外部的新值。


但它并没有发生。


谁能解释为什么?


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)

}

你可以在这里尝试代码:https : //play.golang.org/p/I-GIdIZ9c6


杨魅力
浏览 163回答 3
3回答

慕哥6287543

您不是在更改函数内部的结构,而是通过将其设置为不同的内存地址来更改值。换句话说,您不是在更改存储在 引用的地址处的对象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)    ...}下面的完整代码(此处为游乐场链接):package mainimport "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)}此外,您可能希望防止 nil 值和返回错误,尤其是对于包内部的函数。

FFIVE

在我们的代码中,您将在函数更改中创建 ttt 的新对象并将其分配给 t 作为参数传递给函数。在 go 中,参数是按值传递的,因此在函数更改结束时,您将值分配给 t 仅适用于函数的范围。为了将更改传播到调用函数,从更改返回值并将其分配回来。已对您的代码进行了更改,请查看 Playground 链接 https://play.golang.org/p/S3GK0JLDHn

回首忆惘然

您将初始化的指针值传递给intByRef并更改取消引用的值。在change您传递未初始化的指针值(又名 nil)并为其分配另一个指针。所以你在做两件不同的事情。您应该知道,当您将指针传递给函数时,您会传递该指针的副本(指向相同的值)。这就是为什么main'st在传递给change. 它指向“旧”内存地址。如果你想改变ttt传递给函数的指针的值,你可以像在 中那样做intByRef,但指针必须被初始化(也就是分配)。否则你会尝试取消引用 nil。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)}
随时随地看视频慕课网APP

相关分类

Go
我要回答