为什么在goroutine中替换此golang指针地址不会更改?

问题描述 投票:-1回答:1

据我了解,当我使用foo := &bar{}创建对象时,我正在为该对象分配新的内存。为什么然后,当我尝试在goroutine中替换* foo时,它没有获得新的指针地址?

package main

import (
    "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
}

playground link

实际:

objects pointer: 0xc00000e030
i: 0 p: 0xc00009a010 n: 5577006791947779410 b: true
i: 1 p: 0xc00009a010 n: 8674665223082153551 b: true
i: 2 p: 0xc00009a010 n: 6129484611666145821 b: true
---
replaced: 0xc00000e030 <-- 0xc00000e040 
objects pointer: 0xc00000e030
i: 0 p: 0xc00000e050 n: 4037200794235010051 b: false
i: 1 p: 0xc00000e050 n: 3916589616287113937 b: false
i: 2 p: 0xc00000e050 n: 6334824724549167320 b: false

预期:

objects pointer: 0xc00000e030
i: 0 p: 0xc00009a010 n: 5577006791947779410 b: true
i: 1 p: 0xc00009a010 n: 8674665223082153551 b: true
i: 2 p: 0xc00009a010 n: 6129484611666145821 b: true
---
replaced: 0xc00000e030 <-- 0xc00000e040 
objects pointer: 0xc00000e040
i: 0 p: 0xc00000e050 n: 4037200794235010051 b: false
i: 1 p: 0xc00000e050 n: 3916589616287113937 b: false
i: 2 p: 0xc00000e050 n: 6334824724549167320 b: false

运行时,值将按我期望的那样更新,但是pobjects中的指针保持不变。我希望在我致电*p.objs = *newObjects

时进行更新

这是编译器的窍门吗?如何获得“对象指针”以更新到新位置?我需要使用更明确的指针指向吗?

编辑:固定比赛条件,并尝试分配给p.objs = newObjects,但没有成功。

pointers go
1个回答
0
投票

除打印输出外,程序可以按预期工作。

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

为了获得最佳视图指针,请使用%p动词而不是%v打印指针。

这里是一个例子。更改

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.