我在我的项目中使用 goroutines,我想将值分配给结构字段,但我不知道我将如何分配通过使用 mongodb 查询获得的值到我正在展示的结构字段结构和查询也是如此。
type AppLoadNew struct{
StripeTestKey string `json:"stripe_test_key" bson:"stripe_test_key,omitempty"`
Locations []Locations `json:"location" bson:"location,omitempty"`
}
type Locations struct{
Id int `json:"_id" bson:"_id"`
Location string `json:"location" bson:"location"`
}
func GoRoutine(){
values := AppLoadNew{}
go func() {
data, err := GetStripeTestKey(bson.M{"is_default": true})
if err == nil {
values.StripeTestKey := data.TestStripePublishKey
}
}()
go func() {
location, err := GetFormLocation(bson.M{"is_default": true})
if err == nil {
values.Locations := location
}
}()
fmt.Println(values) // Here it will nothing
// empty
}
你能帮我把所有的值赋给 AppLoadNew
结构吗。
最佳答案
在 Go 中,没有值对于并发读写(来自多个 goroutines)是安全的。您必须同步访问。
可以使用 sync.Mutex
保护从多个 goroutine 读取和写入变量或 sync.RWMutex
,但在您的情况下还涉及其他内容:您应该等待 2 个启动的 goroutines 完成。为此,首选解决方案是 sync.WaitGroup
.
并且由于 2 个 goroutines 写入一个结构的 2 个不同字段(充当 2 个不同的变量),因此它们不必相互同步(请在此处查看更多信息:Can I concurrently write different slice elements)。这意味着使用 sync.WaitGroup
就足够了。
这是使它安全和正确的方法:
func GoRoutine() {
values := AppLoadNew{}
wg := &sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
data, err := GetStripeTestKey(bson.M{"is_default": true})
if err == nil {
values.StripeTestKey = data.StripeTestKey
}
}()
wg.Add(1)
go func() {
defer wg.Done()
location, err := GetFormLocation(bson.M{"is_default": true})
if err == nil {
values.Locations = location
}
}()
wg.Wait()
fmt.Println(values)
}
请参阅 Go Playground 上的(稍作修改的)工作示例.
查看相关/类似问题:
Reading values from a different thread
golang struct concurrent read and write without Lock is also running ok?
关于go - 如何在运行例程时将值分配给结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54457213/