You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go-Kit中Endpoint创建的上下文传递与执行机制技术问询

Go-Kit 代码实现与技术疑问解答

代码实现片段

1. 创建Get Endpoint

func MakeGetEndpoint(srv Service) endpoint.Endpoint {
    return func(ctx context.Context, request interface{}) (interface{}, error) {
        _ = request.(getRequest) // we really just need the request, we don't use any value from it
        d, err := srv.Get(ctx)
        if err != nil {
            return getResponse{d, err.Error()}, nil
        }
        return getResponse{d, ""}, nil
    }
}

2. 映射Endpoints

// mapping endpoints
endpoints := napodate.Endpoints{
    GetEndpoint:      napodate.MakeGetEndpoint(srv)
}

3. Endpoints的Get方法封装

func (e Endpoints) Get(ctx context.Context) (string, error) {
    req := getRequest{}
    resp, err := e.GetEndpoint(ctx, req)
    if err != nil {
        return "", err
    }
    getResp := resp.(getResponse)
    if getResp.Err != "" {
        return "", errors.New(getResp.Err)
    }
    return getResp.Date, nil
}

技术疑问解答

  • 疑问1:如何确保调用e.GetEndpoint(ctx, req)时传入的ctx与MakeGetEndpoint中使用的ctx是同一个?
    Go语言中context.Context是接口类型,参数传递时虽为值传递,但接口副本指向的底层上下文实例是同一个。你的代码里,调用e.GetEndpoint(ctx, req)传入的ctx会直接作为参数传递给MakeGetEndpoint返回的匿名函数,该匿名函数没有对ctx做任何修改或替换,直接将其传给srv.Get(ctx),因此二者必然是同一个上下文实例,无需额外操作即可保证一致性。

  • 疑问2:MakeGetEndpoint实际何时执行?它又是如何获取srv、ctx和request的?

    1. 执行时机:在执行endpoints := napodate.Endpoints{GetEndpoint: napodate.MakeGetEndpoint(srv)}初始化Endpoints结构体时,MakeGetEndpoint会被调用,返回一个endpoint.Endpoint类型的匿名函数并赋值给GetEndpoint字段。
    2. 获取srv:srv是作为MakeGetEndpoint的入参直接传入的,借助Go的闭包特性,返回的匿名函数会捕获这个srv变量,后续调用匿名函数时可直接使用。
    3. 获取ctx和request:ctx和request是在调用e.GetEndpoint(ctx, req)时,作为参数传递给MakeGetEndpoint返回的匿名函数的,匿名函数的参数列表明确声明了这两个参数,调用时直接传入即可。

内容的提问来源于stack exchange,提问作者Lawliet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:05:58