面试题答案
一键面试package main
import (
"fmt"
"sync"
)
func worker(wg *sync.WaitGroup, resultChan chan error) {
defer wg.Done()
// 模拟网络请求或文件读写等操作可能出现的错误
err := simulateOperation()
if err != nil {
resultChan <- err
return
}
resultChan <- nil
}
func simulateOperation() error {
// 这里简单返回一个错误示例
return fmt.Errorf("simulated error")
}
func main() {
var wg sync.WaitGroup
resultChan := make(chan error)
wg.Add(1)
go worker(&wg, resultChan)
go func() {
wg.Wait()
close(resultChan)
}()
for err := range resultChan {
if err != nil {
fmt.Printf("Error in goroutine: %v\n", err)
}
}
}
代码解释:
-
worker函数:
- 接收一个
sync.WaitGroup
指针和一个error
类型的通道resultChan
。 - 使用
defer wg.Done()
确保goroutine
结束时通知WaitGroup
。 - 调用
simulateOperation
模拟可能产生错误的操作。 - 如果操作产生错误,将错误发送到
resultChan
,然后返回。 - 如果没有错误,也向
resultChan
发送nil
。
- 接收一个
-
simulateOperation函数:
- 简单返回一个错误,模拟实际操作中的错误情况。
-
main函数:
- 创建一个
sync.WaitGroup
和一个error
类型的通道resultChan
。 - 使用
wg.Add(1)
表示有一个goroutine
需要等待。 - 启动
worker
goroutine
。 - 使用一个匿名
goroutine
等待worker
goroutine
完成,完成后关闭resultChan
通道。 - 通过
for... range
循环从resultChan
通道接收错误信息,并在主程序中进行统一处理。如果接收到非nil
的错误,打印错误信息。这样既实现了在goroutine
中捕获和处理错误,并将错误信息传递到主程序,同时利用defer
和sync.WaitGroup
确保了goroutine
资源的正确释放。
- 创建一个