为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
杨魅力 2021-11-29 19:32:13
我通过引用将结构传递给函数。我期待如果我在函数内部定义和更改结构,我可以获得外部的新值。但它并没有发生。谁能解释为什么?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}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
查看完整描述

3 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

您不是在更改函数内部的结构,而是通过将其设置为不同的内存地址来更改值。换句话说,您不是在更改存储在 引用的地址处的对象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 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)

}

此外,您可能希望防止 nil 值和返回错误,尤其是对于包内部的函数。


查看完整回答
反对 回复 2021-11-29
?
FFIVE

TA贡献1797条经验 获得超6个赞

在我们的代码中,您将在函数更改中创建 ttt 的新对象并将其分配给 t 作为参数传递给函数。在 go 中,参数是按值传递的,因此在函数更改结束时,您将值分配给 t 仅适用于函数的范围。为了将更改传播到调用函数,从更改返回值并将其分配回来。

已对您的代码进行了更改,请查看 Playground 链接 https://play.golang.org/p/S3GK0JLDHn


查看完整回答
反对 回复 2021-11-29
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

您将初始化的指针值传递给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)

}


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信