
本文详解如何使用 redigo 客户端在 go 中正确读取 redis 中的 list 类型数据,指出误用 `get` 命令导致 `wrongtype` 错误的根本原因,并提供可直接使用的 `lrange` 实现方案及健壮性增强建议。
Redis 中不同数据类型需对应专用命令操作:GET 仅适用于 String 类型,而对 List、Set、Hash 等复合类型调用 GET 会触发 WRONGTYPE Operation against a key holding the wrong kind of value 错误——这正是你代码中 conn.Do("GET", key) 报错的根源。
要获取一个 Redis List 的全部元素,必须使用列表专用命令 LRANGE,其语法为 LRANGE key start stop。传入 0 作为起始索引、-1 作为结束索引,即可返回列表所有元素(从头到尾):
func GetValues(key string) ([]string, error) {
reply, err := conn.Do("LRANGE", key, 0, -1)
if err != nil {
return nil, err // 避免 log.Fatal,便于上层错误处理
}
return redis.Strings(reply) // 将 []interface{} 转为 []string
}✅ 关键说明:redis.Strings() 是 Redigo 提供的便捷转换函数,它将 LRANGE 返回的 []interface{}(每个元素为 []byte)自动解码为 []string。若列表为空,LRANGE 返回空切片 []interface{},redis.Strings() 也会返回空 []string,行为安全。
在调用前,建议先通过 TYPE 命令校验键类型(如你的 RetrieveValue 所示),但生产环境更推荐防御性编程:直接捕获 redis.ErrNil(键不存在)和类型错误,并做日志记录或降级处理:
func RetrieveValue() {
results, err := GetValues(recentItemKey)
if err != nil {
log.Printf("Failed to retrieve list %s: %v", recentItemKey, err)
return
}
fmt.Printf("Retrieved %d items:\n", len(results))
for i, val := range results {
fmt.Printf("[%d] %s\n", i, val)
}
}? 注意事项总结:
- ❌ 禁止对 List 类型键使用 GET、SET、INCR 等字符串命令;
- ✅ 列表操作应使用 LPUSH/RPUSH(写)、LRANGE/LPOP/RPOP(读/删)等专用命令;
- ⚠️ LRANGE key 0 -1 效率高且安全,但若列表极大(百万级),应分页拉取(如 LRANGE key 0 999)避免阻塞 Redis;
- ? 生产代码中务必检查 err 并避免 log.Fatal(会导致整个进程退出),改用返回错误并由调用方决策重试或告警。
掌握类型与命令的严格对应关系,是高效、稳定使用 Redis 的基石。










