在 Gin 框架中,c.Set 和 c.Get 提供了一种方便的方式,用于在请求生命周期内传递和共享数据。它们通常用于中间件和处理函数之间的数据传递。
1. c.Set 和 c.Get 的基本用法
设置数据:c.Set
c.Set 用于存储键值对数据到 Context 中,数据的存储类型为 interface{}:
c.Set("key", "value")
获取数据:c.Get
c.Get 用于获取存储在 Context 中的数据,同时返回两个值:数据和一个布尔值,布尔值表示数据是否存在。
value, exists := c.Get("key")
if exists {
// 使用 value
} else {
// 处理未找到的情况
}
强制获取:c.MustGet
c.MustGet 用于直接获取数据,若数据不存在会引发 panic,因此适合在明确知道键存在的情况下使用:
value := c.MustGet("key").(string) // 需要进行类型断言
2. 示例代码
中间件传递数据
通过中间件设置参数,后续处理函数可以直接获取:
r := gin.Default()
// 中间件设置参数
r.Use(func(c *gin.Context) {
c.Set("user_id", 12345) // 设置用户 ID
c.Next() // 继续后续操作
})
// 获取设置的参数
r.GET("/profile", func(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(400, gin.H{"error": "user_id not found"})
return
}
c.JSON(200, gin.H{"user_id": userID})
})
r.Run()
链式传递
数据在整个请求生命周期内有效,可以在多个中间件和路由处理函数中共享:
r := gin.Default()
// 中间件 1
r.Use(func(c *gin.Context) {
c.Set("trace_id", "123abc") // 设置 trace_id
c.Next()
})
// 中间件 2
r.Use(func(c *gin.Context) {
traceID := c.MustGet("trace_id").(string)
c.Set("new_key", traceID+"_extra") // 基于 trace_id 设置新值
c.Next()
})
// 处理函数
r.GET("/trace", func(c *gin.Context) {
value, _ := c.Get("new_key")
c.JSON(200, gin.H{"trace_id": value})
})
r.Run()
3. 使用注意事项
-
生命周期限制
c.Set和c.Get仅在当前请求的生命周期内有效,请求结束后数据会被清除,不能跨请求传递。 -
类型安全
使用c.Get获取数据时需要手动进行类型断言,否则会导致运行时错误。value, _ := c.Get("key") strValue, ok := value.(string) // 类型断言 if !ok { // 错误处理 } -
键名冲突
避免使用过于通用的键名,例如id、key等,建议使用特定的前缀,如user_id或request_trace_id。 -
性能影响
c.Set和c.Get本质是对一个map的操作,性能影响通常可以忽略,但在高并发场景下,尽量减少不必要的使用。

2148

被折叠的 条评论
为什么被折叠?



