MST

星途 面试题库

面试题:Go语言Goroutine错误处理中的select用法

假设你有多个Goroutine同时执行不同的任务,每个Goroutine可能会返回不同类型的错误。请描述如何使用`select`语句来优雅地处理这些Goroutine的错误,并给出具体代码示例。
37.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 处理思路
    • 使用select语句可以监听多个通道。每个Goroutine可以将其执行结果(包括可能的错误)发送到对应的通道。
    • select语句中,通过不同的case来处理不同通道传来的数据或错误。
  2. 代码示例
package main

import (
    "fmt"
)

func task1(resultChan chan<- string, errChan chan<- error) {
    // 模拟任务执行
    var err error
    var res string
    // 假设这里执行任务出现错误
    err = fmt.Errorf("task1 error")
    if err != nil {
        errChan <- err
    } else {
        res = "task1 result"
        resultChan <- res
    }
    close(resultChan)
    close(errChan)
}

func task2(resultChan chan<- string, errChan chan<- error) {
    // 模拟任务执行
    var err error
    var res string
    // 假设这里任务执行成功
    res = "task2 result"
    if err != nil {
        errChan <- err
    } else {
        resultChan <- res
    }
    close(resultChan)
    close(errChan)
}

func main() {
    task1ResultChan := make(chan string)
    task1ErrChan := make(chan error)
    task2ResultChan := make(chan string)
    task2ErrChan := make(chan error)

    go task1(task1ResultChan, task1ErrChan)
    go task2(task2ResultChan, task2ErrChan)

    for i := 0; i < 2; i++ {
        select {
        case res := <-task1ResultChan:
            fmt.Println("Task1 result:", res)
        case err := <-task1ErrChan:
            fmt.Println("Task1 error:", err)
        case res := <-task2ResultChan:
            fmt.Println("Task2 result:", res)
        case err := <-task2ErrChan:
            fmt.Println("Task2 error:", err)
        }
    }
}

在上述代码中:

  • 定义了两个任务task1task2,每个任务有对应的结果通道和错误通道。
  • main函数中启动这两个任务的Goroutine。
  • 使用select语句在不同的case中处理每个任务的结果和错误。for循环确保所有的通道操作都能被处理(这里假设只有两个任务,所以循环次数为2)。