package gctx
import (
"context"
"fmt"
"reflect"
)
type body[T any] struct {
Value T
}
type typeKey[T any] struct {
}
func Put[T any](ctx context.Context, value T) context.Context {
key := typeKey[body[T]]{}
return context.WithValue(ctx, key, body[T]{Value: value})
}
func Get[T any](ctx context.Context) (T, error) {
key := typeKey[body[T]]{}
value, ok := ctx.Value(key).(body[T])
if !ok {
var zero T
return zero, errors.New("not found")
}
return value.Value, nil
}
1
povsister 85 天前 via iPhone
这种代码写的误人子弟。。
官方 value context 的使用说明你是一点没读啊。 |
4
tairan2006 85 天前 via Android
官方推荐 type alias 就挺简单的
|
5
lrh3321 85 天前 via Android
我要取一个具体的 interface 出来呢?比如我只要 type interface Logger{Info(any)},我不关心具体类型,你这样要存进去还是要做额外处理
|
6
dingyaguang117 85 天前
没太看明白,类型做 key ?每种类型只能存一个数据?
|
7
povsister 85 天前
@8520ccc
哥们我既没人身攻击也没任何脏字。。你这还是有点脆弱了啊。 搁 Linus Torvalds 这种攻击性拉满的,就该直接骂你代码是 trash 了(斜眼笑 不过给个建议,写偏基础性质的代码,务必搞懂每一行代码的作用和大致原理,尤其是参数上的一些设计,你写的时候就不好奇为什么 value context 的 key 和 value 都是 interface 类型么。 不然就会有你这连 value context 设计和原理都没读的闹的笑话了。 |
8
8520ccc OP @dingyaguang117 对 因为我用这个方法主要存的是 *Struct 基本不存在需要一个结构体需要存多份的情况
|
10
povsister 85 天前
|
11
8520ccc OP |
12
8520ccc OP @lrh3321 依然可用 直接存 只是要注意 存进去时的类型 一定要是 Logger
``` package gctx import ( "context" "log" "testing" ) // MockLogger 是一个实现 Logger 接口的模拟结构体 type MockLogger struct { lastMessage any } func (m *MockLogger) Info(msg any) { log.Println("MockLogger:", msg) m.lastMessage = msg } type Logger interface { Info(msg any) } func TestLoggerContextStorage(t *testing.T) { // 创建一个基础 context ctx := context.Background() // 创建一个 MockLogger 实例 logger := &MockLogger{} // 将 logger 存储到 context 中 ctx = Put(ctx, Logger(logger)) // 从 context 中检索 logger retrievedLogger, err := Get[Logger](ctx) if err != nil { t.Fatalf("Failed to retrieve logger from context: %v", err) } retrievedLogger.Info("Test log message") // 检查检索到的 logger 是否是原始 logger if retrievedLogger != logger { t.Errorf("Retrieved logger is not the same as the original logger") } // 使用检索到的 logger testMessage := "Test log message" retrievedLogger.Info(testMessage) // 验证消息是否正确记录 if logger.lastMessage != testMessage { t.Errorf("Expected last message to be %q, but got %q", testMessage, logger.lastMessage) } // 测试检索不存在的类型 _, err = Get[string](ctx) if err == nil { t.Error("Expected error when retrieving non-existent type, but got nil") } } ``` |
15
FarmerChillax 85 天前
一楼说的没错,你这确实误人子弟。建议阅读官方 context 文档: https://pkg.go.dev/context#WithValue
一些大型项目/框架中的血泪史: - https://github.com/gin-gonic/gin/issues/3888 - https://github.com/gin-gonic/gin/issues/4040 最后建议在帖子后面追加说明吧,不然这真的误人子弟 |
16
edcopclub 85 天前 via Android
go 是怎么判断两个变量是==的?
|