如何创建指定次数的信号序列?Go语言实现优化问询
优化方案分析
你的实现本身是可行的,但确实可以通过简化逻辑让代码更优雅,核心是去掉不必要的done通道,因为我们明确知道需要生成N次信号,直接基于计数控制循环即可:
方案一:直接循环计数(最简洁)
这种方式完全不需要额外的通道或select,逻辑直接清晰:
func main() { N := 10 T := 100 * time.Millisecond var wg sync.WaitGroup wg.Add(1) ticker := time.NewTicker(T) defer ticker.Stop() go func() { defer wg.Done() // 直接循环N次,每次等待ticker信号 for i := 0; i < N; i++ { t := <-ticker.C fmt.Println("Tick at", t) } }() wg.Wait() fmt.Println("DONE") }
方案二:保留select(适配未来扩展)
如果后续需要支持外部触发停止(比如用户中断),可以用context替代done通道,让代码更符合Go的惯用模式:
import "context" func main() { N := 10 T := 100 * time.Millisecond var wg sync.WaitGroup ctx, cancel := context.WithCancel(context.Background()) defer cancel() wg.Add(1) ticker := time.NewTicker(T) defer ticker.Stop() go func() { defer wg.Done() count := 0 for { select { case <-ctx.Done(): return case t := <-ticker.C: fmt.Println("Tick at", t) count++ if count == N { cancel() return } } } }() wg.Wait() fmt.Println("DONE") }
原写法的问题点
你原代码中用done通道给自己发信号的逻辑虽然能运行,但属于冗余设计——因为我们已经明确知道要执行N次,不需要额外的通道来触发退出,直接通过循环计数就能完成任务,减少了不必要的通道操作和select分支。
内容的提问来源于stack exchange,提问作者Picci
相关产品推荐
相关产品推荐

