在Go中,同时迭代2个集合的最佳方法是什么?
在我的程序中,我有一个函数创建两个数组,另一个函数需要同时迭代它们(在每次迭代中访问两个数组中的第i个元素).
如果我有一个输入,我会在第一个函数(而不是数组)中创建一个通道,并使用范围循环从各种goroutine迭代它.
在这种情况下,是否有一个比创建索引通道并使用它来访问数组更简单的解决方案?
func main() {
// Prepare two arrays.
arrA := [12]int{1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}
arrB := arrA
// Create a channel with the indexes.
c := make(chan int, len(arrA))
for i := range arrA {
c <- i
}
close(c)
poolSize := 3
var wg sync.WaitGroup
wg.Add(poolSize)
for i := 1; i <= poolSize; i++ {
go func() {
defer wg.Done()
for j := range c {
fmt.Printf("%v == %v\n", arrA[j], arrB[j])
}
}()
}
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
进去有一句话
"不要通过共享内存进行通信,通过通信共享内存"
它基本归结为;
"不要在两个goroutine之间共享状态,而是使用通道传递例程之间所需的值"
这可能是你简化的例子的双积,但不是合格的indicies,你为什么不能限制的范围arrA,并arrB成为一个单一的goroutine,某种生产者或发电机,将发送的值内.这些值的接收者可以对它们进行工作,在这种情况下是相等的比较.
type pair struct {
a, b int
}
c := make(chan pair, len(arrA))
for i := range arrA {
c <- pair{a: arrA[i], b: arrB[i]}
}
close(c)
poolSize := 3
var wg sync.WaitGroup
wg.Add(poolSize)
for _ := range poolSize {
go func() {
defer wg.Done()
for p := range c {
fmt.Printf("%v == %v\n", p.a, p.b)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一个微小的变化,但好处是:
chan pair库中其他位置的代码函数,因为它们不直接访问特定数组中的值,而是传递它们所需的所有值.扩展这个; 假设您只需要来自arrB索引的值而不关心索引,那么您应该在通道上发送该值,并删除对该pair类型的需求.
| 归档时间: |
|
| 查看次数: |
87 次 |
| 最近记录: |