面试题答案
一键面试在Go语言中,处理Goroutine错误常见方式如下:
- 通过返回值处理错误:在函数内部进行错误检查和处理,并将错误作为返回值返回。
package main import ( "fmt" ) func divide(a, b int) (int, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil }
- 使用
sync.WaitGroup
和通道处理子Goroutine错误:package main import ( "fmt" "sync" ) func worker(wg *sync.WaitGroup, errChan chan error) { defer wg.Done() // 模拟可能出错的操作 if someCondition { errChan <- fmt.Errorf("worker error") return } errChan <- nil } func main() { var wg sync.WaitGroup errChan := make(chan error) wg.Add(1) go worker(&wg, errChan) go func() { wg.Wait() close(errChan) }() for err := range errChan { if err != nil { fmt.Printf("Caught error: %v\n", err) } } }
- 使用
context.Context
处理错误:可以在context
中传递取消信号或携带错误信息。package main import ( "context" "fmt" ) func worker(ctx context.Context) error { select { case <-ctx.Done(): return ctx.Err() default: // 模拟正常工作 return nil } } func main() { ctx, cancel := context.WithCancel(context.Background()) go func() { err := worker(ctx) if err != nil { fmt.Printf("Caught error: %v\n", err) } }() // 模拟一段时间后取消 cancel() }
在主Goroutine中捕获并处理子Goroutine中的错误,通常采用上述第二点的方式,通过通道将子Goroutine的错误传递出来,主Goroutine从通道中接收错误并处理。如代码示例:
package main
import (
"fmt"
"sync"
)
func subGoroutine(wg *sync.WaitGroup, errChan chan error) {
defer wg.Done()
// 模拟子Goroutine出错
err := someFunctionThatMightFail()
if err != nil {
errChan <- err
return
}
errChan <- nil
}
func someFunctionThatMightFail() error {
// 实际逻辑,这里简单返回一个错误示例
return fmt.Errorf("simulated error")
}
func main() {
var wg sync.WaitGroup
errChan := make(chan error)
wg.Add(1)
go subGoroutine(&wg, errChan)
go func() {
wg.Wait()
close(errChan)
}()
for err := range errChan {
if err != nil {
fmt.Printf("Main Goroutine caught error: %v\n", err)
}
}
}