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

为什么这个golang指针地址在goroutine中替换时不会改变?

为什么这个golang指针地址在goroutine中替换时不会改变?

Go
慕无忌1623718 2022-06-06 16:49:26
我的理解是,当我创建一个对象时,foo := &bar{}我正在为该对象分配新内存。那么,当我尝试在 goroutine 中替换 *foo 时,为什么它没有获得新的指针地址?package mainimport (    "fmt"    "math/rand"    "sync"    "time")type pointerToObjects struct {    objs *objects}type objects struct {    sliceOfObject []*object}type object struct {    number  int    boolean bool}func main() {    p := &pointerToObjects{objs: newObjects()}    mu := &sync.Mutex{}    for _, o := range p.objs.sliceOfObject {        o.setBool(true)    }    // goroutine 1    go func() {        ticker := time.NewTicker(time.Second)        defer ticker.Stop()        for range ticker.C {            mu.Lock()            fmt.Printf("objects pointer: %v\n", &p.objs)            for i, o := range p.objs.sliceOfObject {                fmt.Printf("i: %d p: %v n: %d b: %t\n", i, &o, o.number, o.boolean)            }            fmt.Print("---\n")            mu.Unlock()        }    }()    // goroutine 2    go func() {        ticker := time.NewTicker(time.Second * 2)        defer ticker.Stop()        for range ticker.C {            newObjects := &objects{sliceOfObject: newSliceOfObject()}            mu.Lock()            p.objs = newObjects            mu.Unlock()            fmt.Printf("replaced: %v <-- %v \n", &p.objs, &newObjects)        }    }()    // let the goroutines run for 10 seconds    time.Sleep(time.Second * 10)}func newObjects() *objects {    objs := &objects{}    objs.sliceOfObject = newSliceOfObject()    return objs}func newSliceOfObject() []*object {    var sliceObjs []*object    for i := 0; i < 3; i++ {        sliceObjs = append(sliceObjs, newObject())    }    return sliceObjs}func newObject() *object {    return &object{number: rand.Int()}}func (obj *object) setBool(b bool) {    obj.boolean = b}运行时,值会按我的预期更新,但指向的指针p保持objects不变。我希望它会在我打电话时更新*p.objs = *newObjects这是编译器的把戏吗?如何获取“对象指针”以更新到新位置?我需要使用更明确的指针吗?编辑:修复了比赛条件并尝试分配p.objs = newObjects但没有成功。
查看完整描述

1 回答

?
哆啦的时光机

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

除打印输出外,该程序按您预期的方式工作。

要打印变量的值,请使用 fmt.Printf 参数列表中的变量。不要传递变量的地址。变量的值和变量的地址是不同的东西。

为了更好地查看指针,请使用%p动词而不是. 打印指针%v

这是一个例子。改变

        fmt.Printf("replaced: %v <-- %v \n", &p.objs, &newObjects)

        fmt.Printf("replaced: %p <-- %p \n", p.objs, newObjects)

标题中提到的与使用 goroutine 无关的问题。


查看完整回答
反对 回复 2022-06-06
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

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