据我了解,当我使用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
}
实际:
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
运行时,值将按我期望的那样更新,但是p
至objects
中的指针保持不变。我希望在我致电*p.objs = *newObjects
这是编译器的窍门吗?如何获得“对象指针”以更新到新位置?我需要使用更明确的指针指向吗?
编辑:固定比赛条件,并尝试分配给p.objs = newObjects
,但没有成功。
除打印输出外,程序可以按预期工作。
要打印变量的值,请使用fmt.Printf参数列表中的变量。不要传递变量的地址。变量的值和变量的地址是不同的东西。
为了获得最佳视图指针,请使用%p
动词而不是%v
打印指针。
这里是一个例子。更改
fmt.Printf("replaced: %v <-- %v \n", &p.objs, &newObjects)
到
fmt.Printf("replaced: %p <-- %p \n", p.objs, newObjects)
标题中提到的与使用goroutine无关的问题。