gpt4 book ai didi

arrays - 同时遍历两个集合

转载 作者:IT王子 更新时间:2023-10-29 01:23:07 27 4
gpt4 key购买 nike

在 Go 中,同时遍历 2 个集合的最佳方法是什么?

在我的程序中,我有一个函数创建两个数组,另一个函数需要同时迭代它们(在每次迭代中访问两个数组中的第 I 个元素)。

如果我只有一个输入,我会在第一个函数中创建一个 channel (而不是数组),并使用范围循环从各种 goroutine 对其进行迭代。

在这种情况下,是否有比创建索引 channel 并使用它来访问数组更简单的解决方案?

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()
}

最佳答案

围棋里有一句话

"Don't communicate by sharing memory, share memory by communicating"

基本上可以归结为;

“不要在 2 个 goroutine 之间共享状态,而是使用 channel 在例程之间传递所需的值”

它可能是您简化示例的副产品,但为什么不传递索引,为什么不能将 arrAarrB 的范围限制在内部单个 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)
}
}
}

这似乎是一个微不足道的小改动,但好处是:

  1. 隔离:您将 arrA 和 arrB 的访问器范围限制为单个生产 goroutine,限制稍后代码中竞争条件/复杂逻辑/错误的范围。
  2. 重用:您可以在代码库的其他地方重用使用 chan 对 的代码函数,因为它们不直接访问特定数组中的值,而是全部传递他们需要的值(value)观。

扩展这个;假设您只需要 arrB 中的值而不关心索引,那么您应该在 channel 上发送该值,并删除对 pair 类型的需要。

关于arrays - 同时遍历两个集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51137709/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com