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

Go语言跨包读取context中存储的struct值返回nil问题排查

错误原因

Go 语言的context.WithValue在匹配键时,会同时校验键的类型和值,你当前的问题本质是两个包下的键类型不匹配:

  • client包定义的applicationState{}类型标识为client.applicationState
  • server包定义的applicationState{}类型标识为server.applicationState
    二者是完全独立的不同类型,用server.applicationState{}作为键自然无法查询到client.applicationState{}存入的值,因此返回nil。
修复方案

方案1:统一使用同一键类型(推荐)

为了避免键冲突同时简化调用,建议将context存取逻辑封装在定义键的包内,对外暴露方法,其他包直接调用即可:

  1. 调整client包代码,新增存取封装:
package client

import "context"

type applicationState struct{} // 包私有键,避免外部冲突
type ApplicationState struct {
    RequestID         string
    RequestParameters interface{}
    RequestPath       string
}

// 存入ApplicationState到context
func WithApplicationState(ctx context.Context, state ApplicationState) context.Context {
    return context.WithValue(ctx, applicationState{}, state)
}

// 从context取出ApplicationState
func GetApplicationState(ctx context.Context) (ApplicationState, bool) {
    state, ok := ctx.Value(applicationState{}).(ApplicationState)
    return state, ok
}
  1. 存值侧原有代码调整为调用封装方法:
appState := ApplicationState{
    RequestID:         "123",
    RequestParameters: req,
    RequestPath:       "abc/def",
}
newCtx := WithApplicationState(ctx, appState)
return handler(newCtx, req)
  1. server包取值时直接调用client包的取值方法即可:
package server

import "your_project_path/client" // 导入client包

state, ok := client.GetApplicationState(ctx)
fmt.Println("values from context is:", state, ok)

方案2:直接复用已有键类型

如果不想做封装,也可以在server包直接使用client包的键类型,但注意如果client包的applicationState是首字母小写的私有类型,这个方式不可用,必须用方案1封装。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:03