可以预测大小 time.Time.MarshalBinary() 返回的缓冲区 - 以协助其他自定义类型的二进制解组。尝试为我的类型编写一个紧凑的 BinaryMarshaler(即避免存储不必要的大小标记):type Item struct { t time.Time m *pb.Device // implements proto.Message - so use proto.Marshal(...) to Marshal}这两个字段都有 BinaryMarshaler,所以这应该很容易。第一遍,是将两个编组附加[]bytes在一起(时间第一,proto.Message 第二)。但是如何Unmarshal,因为time.Time.UnmarshalBinary不指示消耗了多少字节 - 那么应该使用什么偏移量来开始proto.Message解组?检查时间源建议time.Time.MarshalBinary()将始终返回 15 个字节(第一个字节包含 的算法版本1)。1.2.2从 go 版本到今天(1.14),这似乎都是正确的。因此,可以计算 a 消耗的字节数time.UnmarshalBinary以协助自定义BinaryUnmarshalers- 并避免硬编码假设,例如:func (i *Item) UnmarshalBinary(b []byte) error { const ( timeV = 1 timeV1Len = 15 ) if len(b) == 0 { *i = Item{} // no data - set to zero value return nil } if b[0] != timeV { return fmt.Errorf("time.Time binary marshaled at unsupported version %d (expected version %d)", b[0], timeV) } if len(b) < timeV1Len { return fmt.Errorf("data too short: should be >= %d bytes, got %d byte(s)", timeV1Len, len(b)) } if err = i.t.UnmarshalBinary(b[:timeV1Len]); err != nil { return err } if len(b[timeV1Len:]) == 0 { i.m = nil // no more data, so set Message nil return nil } i.m = &pb.Device{} return proto.Unmarshal(b[timeV1Len:], i.m)}
1 回答
不负相思意
TA贡献1777条经验 获得超10个赞
据我所知,输出的大小MarshalBinary不受Go 1 Compatibility Promise的约束:
未指定的行为。Go 规范试图明确该语言的大多数属性,但有些方面未定义。依赖于这种未指定行为的程序可能会在未来的版本中中断。
Time.MarshalBinary没有指定其输出的大小,因此它会被视为“未指定的行为”。
- 1 回答
- 0 关注
- 169 浏览
添加回答
举报
0/150
提交
取消
