MST

星途 面试题库

面试题:Go语言中通道与Goroutine错误处理之复杂场景

假设有多个Goroutine并发地向一个通道发送数据,而另一个Goroutine从该通道接收数据并处理,同时在处理过程中可能会出现不同类型的错误(如网络错误、数据解析错误等)。请设计一种合理的错误处理机制,能够区分不同类型的错误,并在主Goroutine中进行相应的处理,同时确保程序的健壮性和性能。请详细描述设计思路并编写关键代码片段。
10.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义错误类型:为不同类型的错误定义独立的错误类型,方便区分。
  2. 封装数据与错误:发送到通道的数据结构不仅包含实际数据,还包含可能发生的错误。
  3. 接收与处理:接收方在处理数据时,检查错误并将其传递给主Goroutine。
  4. 主Goroutine处理:主Goroutine根据不同的错误类型进行相应处理,同时保证程序不会因错误而崩溃。

关键代码片段

package main

import (
    "errors"
    "fmt"
)

// 定义不同类型的错误
var (
    ErrNetwork = errors.New("network error")
    ErrParse   = errors.New("data parse error")
)

// 定义数据与错误封装的结构体
type DataWithError struct {
    Data  interface{}
    Error error
}

func main() {
    dataCh := make(chan DataWithError)

    // 模拟多个Goroutine发送数据
    for i := 0; i < 3; i++ {
        go func(id int) {
            var dwErr DataWithError
            // 模拟不同类型错误
            if id == 1 {
                dwErr = DataWithError{Data: "data1", Error: ErrNetwork}
            } else if id == 2 {
                dwErr = DataWithError{Data: "data2", Error: ErrParse}
            } else {
                dwErr = DataWithError{Data: "data3", Error: nil}
            }
            dataCh <- dwErr
        }(i)
    }

    // 接收并处理数据和错误
    go func() {
        for dwErr := range dataCh {
            if dwErr.Error != nil {
                switch dwErr.Error {
                case ErrNetwork:
                    fmt.Printf("Network error occurred while processing data: %v\n", dwErr.Data)
                case ErrParse:
                    fmt.Printf("Parse error occurred while processing data: %v\n", dwErr.Data)
                default:
                    fmt.Printf("Unknown error occurred: %v\n", dwErr.Error)
                }
            } else {
                fmt.Printf("Processed data successfully: %v\n", dwErr.Data)
            }
        }
    }()

    // 防止主Goroutine退出
    select {}
}