我正在尝试使用通道和 goroutines 同时将节点添加到链表中。但是,我似乎做错了什么。这是我到目前为止所写的内容。目前,我的打印功能只是重复第 8 个节点。这似乎适用于其他链接列表,所以我不完全理解这个问题。任何帮助都会很棒。这是我写的代码func makeNodes(ctx context.Context, wg *sync.WaitGroup, ch chan Node) { defer wg.Done() for i := 0; i < 9; i++ { tmp := Node{Data: i, Next: nil} ch <- tmp } <-ctx.Done() return}type Node struct { Data int Next *Node}type List struct { Head *Node Length int Last *Node}func (l *List) addToEnd(n *Node) { if l.Head == nil { l.Head = n l.Last = n l.Length++ return } tmp := l.Last tmp.Next = n l.Last = n l.Length++}func (l List) print() { tmp := l.Head for tmp != nil { fmt.Println(tmp) tmp = tmp.Next } fmt.Println("\n")}func main() { cha := make(chan Node) defer close(cha) ctx := context.Background() ctx, cancel := context.WithCancel(ctx) var wg sync.WaitGroup wg.Add(1) list := List{nil, 0, nil} go makeNodes(ctx, &wg, cha) go func() { for j := range cha { list.addToEnd(&j) } }() cancel() wg.Wait() list.print()}
1 回答

手掌心
TA贡献1942条经验 获得超3个赞
该程序分配一个结构(j在for j:= range循环中)并用从通道读取的内容重复覆盖它。
这导致相同的变量(j位于固定内存位置)被多次添加到列表中。
考虑将通道修改为指针通道。
在main()
cha := make(chan *Node)
然后对于makeNodes() 每次创建一个新节点(通过Node{}),一个新的节点指针被放置到通道中。
func makeNodes(ctx context.Context, wg *sync.WaitGroup, ch chan *Node) {
defer wg.Done()
for i := 0; i < 9; i++ {
tmp := Node{Data: i, Next: nil}
ch <- &tmp
}
<-ctx.Done()
return
}
下面将正确地将每个唯一的 Node 指针添加到列表中。
go func() {
for j := range cha {
list.addToEnd(j)
}
}()
此外,您可能会发现并非所有实体都会进入列表或从频道中读取。您用于同步生产者 ( makeNodes()) 和消费 ( for j:= range) 的方法需要改进。
- 1 回答
- 0 关注
- 122 浏览
添加回答
举报
0/150
提交
取消