Golang使用go-redis存储map[string]string报marshal错误如何解决
报错根因
go-redis 库的Set方法默认仅支持实现了encoding.BinaryMarshaler接口的类型作为值传入,原生map[string]string没有实现该接口,因此无法自动序列化存入Redis,就会触发你遇到的报错。你之前序列化没生效大概率是没有将序列化后的字节流传入Set方法,还是直接传了原始map参数。
方案1:JSON序列化存储(通用方案,支持任意类型存储)
这个方案兼容性最强,不管是Map、结构体还是其他自定义类型都可以用,只需要做一次JSON序列化和反序列化即可,也符合你想要做通用Redis接口的需求。
完整修改后代码:
package main import ( "encoding/json" "fmt" "time" "github.com/go-redis/redis" ) // 全局复用Redis客户端,不要每次操作都新建连接 var redisClient *redis.Client // 初始化只执行一次,创建全局Redis连接 func init() { redisClient = redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, }) } func main() { student := map[string]string{ "id": "st01", "name": "name1", } set("key1", student, 0) get("key1") } // set方法支持传入任意类型的值,实现通用存储 func set(key string, value interface{}, ttl int) bool { // 先将值序列化为JSON字节流 jsonBytes, err := json.Marshal(value) if err != nil { fmt.Println("序列化失败:", err) return false } err = redisClient.Set(key, jsonBytes, time.Duration(ttl)*time.Second).Err() if err != nil { fmt.Println("写入Redis失败:", err) return false } return true } // 通用读取方法,返回原始JSON字符串可按需反序列化为对应类型 func get(key string) bool { val, err := redisClient.Get(key).Result() if err != nil { fmt.Println("读取Redis失败:", err) return false } // 示例:反序列化为map[string]string类型,可根据实际存储的类型调整 var res map[string]string err = json.Unmarshal([]byte(val), &res) if err != nil { fmt.Println("反序列化失败:", err) return false } fmt.Println("读取结果:", res) return true }
方案2:使用Redis Hash结构存储(更适配Map场景)
如果你存储的都是键值对结构的Map,用Redis原生的Hash数据结构更合适,支持单独查询、修改某一个键的值,不需要操作整个数据:
对应修改后的set/get方法:
// 写入Hash结构 func hSet(key string, value map[string]string, ttl int) bool { // 批量写入Hash字段 err := redisClient.HMSet(key, value).Err() if err != nil { fmt.Println("写入Hash失败:", err) return false } // 设置过期时间 if ttl > 0 { redisClient.Expire(key, time.Duration(ttl)*time.Second) } return true } // 读取Hash结构 func hGet(key string) bool { res, err := redisClient.HGetAll(key).Result() if err != nil { fmt.Println("读取Hash失败:", err) return false } fmt.Println("Hash读取结果:", res) return true }
注意事项
- 方案2的参数只能是
map[string]string类型,方案1可以支持任意类型的存储,你可以根据自己的需求选择。 - 一定要复用Redis客户端,不要每次读写都新建连接,会严重消耗连接资源,降低性能。
内容的提问来源于stack exchange,提问作者Black Knight
相关产品推荐
相关产品推荐

