如何在 go 例程为 运行 时将值分配给结构?
How to assign the values to struct while go routines are running?
我在我的项目中使用 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
or sync.RWMutex
, but in your case there is something else involved: you should wait for the 2 launched goroutines to complete. For that, the go-to solution is sync.WaitGroup
.
来保护从多个 goroutine 读取和写入变量
并且由于 2 个 goroutine 写入一个结构的 2 个不同字段(充当 2 个不同的变量),因此它们不必相互同步(请在此处查看更多信息:) .这意味着使用 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)
}
上查看一个(稍作修改的)工作示例
查看相关/类似问题:
您可以将 sync
包与 WaitGroup
一起使用,这是一个示例:
package main
import (
"fmt"
"sync"
"time"
)
type Foo struct {
One string
Two string
}
func main() {
f := Foo{}
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Perform long calculations
<-time.After(time.Second * 1)
f.One = "foo"
}()
wg.Add(1)
go func() {
defer wg.Done()
// Perform long calculations
<-time.After(time.Second * 2)
f.Two = "bar"
}()
fmt.Printf("Before %+v\n", f)
wg.Wait()
fmt.Printf("After %+v\n", f)
}
输出:
Before {One: Two:}
After {One:foo Two:bar}
我在我的项目中使用 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
or sync.RWMutex
, but in your case there is something else involved: you should wait for the 2 launched goroutines to complete. For that, the go-to solution is sync.WaitGroup
.
并且由于 2 个 goroutine 写入一个结构的 2 个不同字段(充当 2 个不同的变量),因此它们不必相互同步(请在此处查看更多信息: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)
}
上查看一个(稍作修改的)工作示例
查看相关/类似问题:
您可以将 sync
包与 WaitGroup
一起使用,这是一个示例:
package main
import (
"fmt"
"sync"
"time"
)
type Foo struct {
One string
Two string
}
func main() {
f := Foo{}
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Perform long calculations
<-time.After(time.Second * 1)
f.One = "foo"
}()
wg.Add(1)
go func() {
defer wg.Done()
// Perform long calculations
<-time.After(time.Second * 2)
f.Two = "bar"
}()
fmt.Printf("Before %+v\n", f)
wg.Wait()
fmt.Printf("After %+v\n", f)
}
输出:
Before {One: Two:}
After {One:foo Two:bar}