1、问题

通常我们使用go-redis用来Get/Set读取或者存储数据时,使用数据类型为string正常,但是使用对象、数组出现以下错误
redis: can't marshal *main.UserArray (implement encoding.BinaryMarshaler)
redis: can't unmarshal *main.UserArray (consider implementing BinaryUnmarshaler)

2、原因

我跟踪了Scan方法,发现以下标记的地方报错,是由于我们未将类型声明encoding.BinaryMarshaler方法

func Scan(b []byte, v interface{}) error {switch v := v.(type) {case nil:return fmt.Errorf("redis: Scan(nil)")case *string:*v = util.BytesToString(b)return nilcase *[]byte:*v = breturn nilcase *int:var err error*v, err = util.Atoi(b)return errcase *int8:n, err := util.ParseInt(b, 10, 8)if err != nil {return err}*v = int8(n)return nilcase *int16:n, err := util.ParseInt(b, 10, 16)if err != nil {return err}*v = int16(n)return nilcase *int32:n, err := util.ParseInt(b, 10, 32)if err != nil {return err}*v = int32(n)return nilcase *int64:n, err := util.ParseInt(b, 10, 64)if err != nil {return err}*v = nreturn nilcase *uint:n, err := util.ParseUint(b, 10, 64)if err != nil {return err}*v = uint(n)return nilcase *uint8:n, err := util.ParseUint(b, 10, 8)if err != nil {return err}*v = uint8(n)return nilcase *uint16:n, err := util.ParseUint(b, 10, 16)if err != nil {return err}*v = uint16(n)return nilcase *uint32:n, err := util.ParseUint(b, 10, 32)if err != nil {return err}*v = uint32(n)return nilcase *uint64:n, err := util.ParseUint(b, 10, 64)if err != nil {return err}*v = nreturn nilcase *float32:n, err := util.ParseFloat(b, 32)if err != nil {return err}*v = float32(n)return errcase *float64:var err error*v, err = util.ParseFloat(b, 64)return errcase *bool:*v = len(b) == 1 && b[0] == '1'return nilcase *time.Time:var err error*v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b))return errcase *time.Duration:n, err := util.ParseInt(b, 10, 64)if err != nil {return err}*v = time.Duration(n)return nilcase encoding.BinaryUnmarshaler:return v.UnmarshalBinary(b)default://在这里报错了return fmt.Errorf("redis: can't unmarshal %T (consider implementing BinaryUnmarshaler)", v)}
}

3、解决方法(对象)

package mainimport ("context""encoding/json""fmt""github.com/go-redis/redis/v8"
)type User struct {UserId   string `json:"user_id"`UserName string `json:"user_name"`
}//序列化
func (m *User) MarshalBinary() (data []byte, err error) {fmt.Println("MarshalBinary")return json.Marshal(m)
}//反序列化
func (m *User) UnmarshalBinary(data []byte) error {fmt.Println("UnmarshalBinary")return json.Unmarshal(data, m)}func main() {var ctx = context.Background()redis := redis.NewClient(&redis.Options{Addr:     "127.0.0.1:6379",Password: "",DB:       0,})user := User{UserId:   "123",UserName: "name",}fmt.Println("设置缓存")err := redis.Set(ctx, "user_key", &user, 0).Err()if err != nil {fmt.Println(err)}result := User{}fmt.Println("读取缓存")err = redis.Get(ctx, "user_key").Scan(&result)if err != nil {fmt.Println(err)}fmt.Println("user对象:", result)
}

4、解决方法(数组)

package mainimport ("context""encoding/json""fmt""github.com/go-redis/redis/v8"
)type User struct {UserId   string `json:"user_id"`UserName string `json:"user_name"`
}
type UserArray []User//序列化
func (m *UserArray) MarshalBinary() (data []byte, err error) {fmt.Println("MarshalBinary")return json.Marshal(m)
}//反序列化
func (m *UserArray) UnmarshalBinary(data []byte) error {fmt.Println("UnmarshalBinary")return json.Unmarshal(data, m)}func main() {var ctx = context.Background()redis := redis.NewClient(&redis.Options{Addr:     "127.0.0.1:6379",Password: "",DB:       0,})userArr := UserArray{}user := User{UserId:   "123",UserName: "name",}userArr = append(userArr, user)fmt.Println("设置缓存")err := redis.Set(ctx, "user_key", &userArr, 0).Err()if err != nil {fmt.Println(err)}result := UserArray{}fmt.Println("读取缓存")err = redis.Get(ctx, "user_key").Scan(&result)if err != nil {fmt.Println(err)}fmt.Println("user数组:", result)
}

redis: can‘t unmarshal *[]User (consider implementing BinaryUnmarshaler)相关推荐

  1. Redis 为什么用跳表而不用平衡树?

    本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...

  2. Redis 为什么用跳表而不用平衡树

    Redis 为什么用跳表而不用平衡树? 本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用s ...

  3. redis中zset底层实现原理

    https://www.cnblogs.com/yuanfang0903/p/12165394.html 阅读目录 一.Zset编码的选择 二.ziplist 三.skiplist 四.skiplis ...

  4. redis的zset的底层实现_redis zset底层实现原理

    一.Zset编码的选择 1.有序集合对象的编码可以是ziplist或者skiplist.同时满足以下条件时使用ziplist编码: 元素数量小于128个 所有member的长度都小于64字节 其他: ...

  5. Redis高频面试题完整版

    文章目录: Redis概述 什么是Redis? Redis的优缺点? Redis为什么常常用做缓存?相比于guava有什么优势? Redis和Memcached的区别与共同点? Redis是单线程还是 ...

  6. Redis Zset的实现为什么用跳表,而不用平衡树?

    之前写过一篇 Redis 数据类型的底层数据结构的实现,其中提到,ZSet 对象的底层数据结构实现之一是跳表. 然后,有读者就问:为什么不使用平衡树(如红黑树.AVL 树)? 我们先来了解下跳表,再来 ...

  7. 《这是全网最硬核redis总结,谁赞成,谁反对?》六万字大合集

    我摊牌了,这篇文章,值得99%的人收藏 此文后续会改为粉丝可见,所以喜欢的请提前关注和收藏,不迷路. 最近有五本我喜欢的redis实体新书,想要的去评论,我写个随机数抽奖包邮送给你. 那么,准备好了吗 ...

  8. 《三天给你聊清楚redis》第1天先唠唠redis是个啥(18629字)

    后端需要知道的关于redis的事,基本都在这里了. 此文后续会改为粉丝可见,所以喜欢的请提前关注. 你的点赞和评论是我创作的最大动力,谢谢. 1.入门 Redis是一款基于键值对的NoSQL数据库,它 ...

  9. 探索Redis设计与实现6:Redis内部数据结构详解——skiplist

    Redis内部数据结构详解(6)--skiplist  2016-10-05 本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skipl ...

最新文章

  1. 死锁产生的原因及四个必要条件
  2. 欢迎使用Markdown编辑器写博客
  3. 实验二 二叉树的操作与实现
  4. n阶完全图边和顶点关系。_正N边型的完全图被分割成几个多边形
  5. myeclipse mysql连接_MyEclipse连接Mysql数据库的方法(一)
  6. P1057 传球游戏
  7. 自动部署 php,Jenkins实现PHP的自动部署
  8. Oracle 20c 新特性:持久化内存数据库 - Persistent Memory Database
  9. hdu 2082 找单词(母函数)
  10. 计算机组装 毕业设计,毕业设计(论文)--计算机组装与维护 .doc
  11. 通俗理解什么是隐马尔科夫模型(hmm)
  12. matlab电力系统建模仿真实验,电力系统建模及仿真课程设计
  13. 互联网电商都是怎么用工厂模式的?
  14. DMA copy和CPU copy
  15. FS4100 锂电充电管理IC输入12V给8.4V充电IC
  16. KETTLE使用通配符匹配多个文件输入到一张表中
  17. 一个人摘了一些桃子,第一天卖掉了一半,又吃了一个,第二天卖掉了一半,又吃了一个,以后天天都是如此处理,到第n天发现桃子只剩下一个桃子,n是参数,返回值是一共摘的桃子数。 求两个数的最大公约数
  18. 51、Vue 单页面应用
  19. mysql 默认排序是什么意思,MySQL 默认排序是什么
  20. 计算机音乐谱生曰快乐,原神乐谱(琴谱)生日快乐

热门文章

  1. PSP编程环境破解个人研究笔记——CYGWIN环境搭建
  2. i.MX6UL -- 网络性能测试 iperf+jperf
  3. 以电影为题材好玩的游戏总结
  4. 利用python爬取历代中国行政图,从先周到中华人民共和国,jpg格式边框带经纬度,可自行配准矢量化
  5. 人力资源机器 android,人力资源机器攻略所有章节过关方法详解
  6. 阿里云安全组规则配置及Tomcat外网访问
  7. LED大屏千兆光纤收发器利亚德洲明LED显示屏诺瓦灵星雨卡莱特凯视达光电转换器
  8. KubeSphere研发总监周小四:在谈容器同质化之前,你得先理解工匠精神
  9. 0x00007FFC8C5325E7 (ucrtbased.dll)处(位于 DataStructure.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFF
  10. 50个最优秀的 Photoshop 实例教程【文字特效篇】