MST

星途 面试题库

面试题:Go中Context在错误处理场景下的常规用法

请描述在Go语言中,当使用Context进行函数间传递并处理错误时,一般会涉及哪些步骤?假设你有一个HTTP处理函数,该函数调用了多个需要使用Context控制生命周期及处理错误的子函数,简要说明代码结构和Context的传递方式。
49.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 涉及步骤

    • 创建Context:一般使用context.Background()作为根Context开始,在HTTP处理中,会从http.Request中获取Context,如ctx := r.Context()
    • 传递Context:将Context作为参数传递给各个需要控制生命周期或处理错误的子函数。
    • 检查错误:在子函数中,通过ctx.Err()检查Context是否被取消或超时,如果ctx.Err() != nil,根据错误类型处理错误,比如返回特定错误信息。
    • 取消操作:如果需要主动取消操作,可使用context.WithCancel创建一个可取消的Context,在合适的时机调用取消函数来通知子函数停止操作。
  2. 代码结构和Context传递方式示例

package main

import (
    "context"
    "fmt"
    "net/http"
)

// 模拟子函数1
func subFunction1(ctx context.Context) error {
    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
        // 正常业务逻辑
        fmt.Println("subFunction1 is running")
        return nil
    }
}

// 模拟子函数2
func subFunction2(ctx context.Context) error {
    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
        // 正常业务逻辑
        fmt.Println("subFunction2 is running")
        return nil
    }
}

// HTTP处理函数
func httpHandler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    // 调用子函数1
    if err := subFunction1(ctx); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 调用子函数2
    if err := subFunction2(ctx); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    w.Write([]byte("Success"))
}

func main() {
    http.HandleFunc("/", httpHandler)
    fmt.Println("Server is running on http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

在上述代码中,httpHandlerhttp.Request获取Context,然后将其传递给subFunction1subFunction2。子函数通过ctx.Done()通道监听Context的取消信号,并在接收到取消信号时返回相应错误,httpHandler根据子函数返回的错误进行处理。