英文:
Pass a result from goroutine to a variable inside the loop
问题
在下面的代码中,如何将slowExternalFunction的结果分配给适当的person?可以通过通道来实现,为了清晰起见,我定义了slowExternalFunction返回int。
type Person struct {
Id int
Name string
WillDieAt int
}
func slowExternalAPI(i int) int {
time.Sleep(10)
willDieAt := i + 2040
return willDieAt
}
func fastInternalFunction(i int) string {
time.Sleep(1)
return fmt.Sprintf("Ivan %v", i)
}
func main() {
var persons []Person
for i := 0; i <= 100; i++ {
var person Person
person.Id = i
person.Name = fastInternalFunction(i)
go func(i int) {
result := slowExternalAPI(i)
person.WillDieAt = result
}(i)
persons = append(persons, person)
}
fmt.Printf("%v", persons)
}
你可以在这里查看代码:https://play.golang.org/p/BRBgtH5ryo
英文:
At the code below how to assign a result from slowExternalFunction to a proper person? It can be done via channels and just for clarity I defined that slowExternalFunction returns int.
type Person struct {
Id int
Name string
WillDieAt int
}
func slowExternalAPI(i int) int {
time.Sleep(10)
willDieAt := i + 2040
return willDieAt
}
func fastInternalFunction(i int) string {
time.Sleep(1)
return fmt.Sprintf("Ivan %v", i)
}
func main() {
var persons []Person
for i := 0; i <= 100; i++ {
var person Person
person.Id = i
person.Name = fastInternalFunction(i)
go slowExternalAPI(i)
person.WillDieAt = 2050 //should be willDieAt from the slowExternalAPI
persons = append(persons, person)
}
fmt.Printf("%v", persons)
}
答案1
得分: 2
要使用通道来完成这个任务,你需要对代码进行相当大的重构。
最小的更改是在 goroutine 中进行赋值:
go func(){
person.WillDieAt = slowExternalFunction(i)
}()
然而,为了使其工作,我们还需要进行其他一些更改:
- 使用指针数组,以便在赋值完成之前就可以添加 person。
- 实现一个等待组,以便在打印结果之前等待所有 goroutine 完成。
以下是带有这些更改的完整 main
函数:
func main() {
var persons []*Person
var wg sync.WaitGroup
for i := 0; i <= 100; i++{
person := &Person{}
person.Id = i
person.Name = fastInternalFunction(i)
wg.Add(1)
go func(){
person.WillDieAt = slowExternalFunction(i)
wg.Done()
}()
persons = append(persons,person)
}
wg.Wait()
for _, person := range persons {
fmt.Printf("%v ", person )
}
}
Playground: https://play.golang.org/p/8GWYD29inC
英文:
To do it using channels you'll have to refactor your code quite a bit.
Smallest change would be to do the assignment in the goroutine:
go func(){
person.WillDieAt = slowExternalFunction(i)
}()
However, to make this work we'd need to make some other changes as well:
- Use an array of pointers so that you can add the person before the assignment finishes.
- Implement a wait group so that you wait for all goroutines to finish before printing the results.
Here's the complete main
function with the changes:
func main() {
var persons []*Person
var wg sync.WaitGroup
for i := 0; i <= 100; i++{
person := &Person{}
person.Id = i
person.Name = fastInternalFunction(i)
wg.Add(1)
go func(){
person.WillDieAt = slowExternalFunction(i)
wg.Done()
}()
persons = append(persons,person)
}
wg.Wait()
for _, person := range persons {
fmt.Printf("%v ", person )
}
}
Playground: https://play.golang.org/p/8GWYD29inC
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论