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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:36:03