Gob解码无法解码寄存器类型后的接口
Gob decode cannot decode interface after register type
我定义了这些类型:
func init() {
gob.RegisterName("MyMessageHeader", MyMessageHeader{})
gob.RegisterName("OtherMsg", OtherMsg{})
}
//
// Messages
//
type MyMessageHeader struct {
MessageId InstanceIdType
OtherId uint64
}
type MyMessage interface {
Id() *MyMessageHeader
}
type otherStruct struct {
X uint8
Y uint8
}
type OtherMsg struct {
MyMessageHeader
OtherField *otherStruct
}
func (m *OtherMsg) Id() *MyMessageHeader {
return &m.MyMessageHeader
}
func MarshalMessage(m MyMessage) ([]byte, error) {
var buff bytes.Buffer
encoder := gob.NewEncoder(&buff)
if err := encoder.Encode(&m); err != nil {
return nil, errors.Newf("Could not marshal message: %v", err)
}
return buff.Bytes(), nil
}
func UnmarshalMessage(buf []byte) (MyMessage, error) {
var msg MyMessage
decoder := gob.NewDecoder(bytes.NewReader(buf))
if err := decoder.Decode(&msg); err != nil {
return nil, errors.Newf("Could not decode my message: %v", err)
}
return msg, nil
}
当我尝试使用 UnmarshalMessage
时出现错误 gob: OtherMsg is not assignable to type MyMessage
。
我对 go examples 中用于编码和解码接口的用法没有任何区别。我做错了什么?
错误消息说:
gob: OtherMsg is not assignable to type MyMessage
这是真的。 MyMessage
是一个接口,它要求实现者类型有一个方法:
Id() *MyMessageHeader
类型OtherMsg
的值在其method set中没有这样的方法,只有一个指向它的指针,即类型*OtherMsg
的值(因为OtherMsg.Id()
有指针接收器)。
要使其工作,请注册一个 *OtherMsg
:
类型的值
gob.RegisterName("OtherMsg", &OtherMsg{})
或者简单地说:
gob.Register(&OtherMsg{})
查看 Go Playground 上的工作示例:
func init() {
gob.Register(&OtherMsg{})
}
func main() {
var m MyMessage = &OtherMsg{
MyMessageHeader: MyMessageHeader{
MessageId: 1,
OtherId: 2,
},
OtherField: "othervalue",
}
data, err := MarshalMessage(m)
if err != nil {
panic(err)
}
m2, err := UnmarshalMessage(data)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", m2)
}
输出(在 Go Playground 上尝试):
&{MyMessageHeader:{MessageId:1 OtherId:2} OtherField:othervalue}
我定义了这些类型:
func init() {
gob.RegisterName("MyMessageHeader", MyMessageHeader{})
gob.RegisterName("OtherMsg", OtherMsg{})
}
//
// Messages
//
type MyMessageHeader struct {
MessageId InstanceIdType
OtherId uint64
}
type MyMessage interface {
Id() *MyMessageHeader
}
type otherStruct struct {
X uint8
Y uint8
}
type OtherMsg struct {
MyMessageHeader
OtherField *otherStruct
}
func (m *OtherMsg) Id() *MyMessageHeader {
return &m.MyMessageHeader
}
func MarshalMessage(m MyMessage) ([]byte, error) {
var buff bytes.Buffer
encoder := gob.NewEncoder(&buff)
if err := encoder.Encode(&m); err != nil {
return nil, errors.Newf("Could not marshal message: %v", err)
}
return buff.Bytes(), nil
}
func UnmarshalMessage(buf []byte) (MyMessage, error) {
var msg MyMessage
decoder := gob.NewDecoder(bytes.NewReader(buf))
if err := decoder.Decode(&msg); err != nil {
return nil, errors.Newf("Could not decode my message: %v", err)
}
return msg, nil
}
当我尝试使用 UnmarshalMessage
时出现错误 gob: OtherMsg is not assignable to type MyMessage
。
我对 go examples 中用于编码和解码接口的用法没有任何区别。我做错了什么?
错误消息说:
gob: OtherMsg is not assignable to type MyMessage
这是真的。 MyMessage
是一个接口,它要求实现者类型有一个方法:
Id() *MyMessageHeader
类型OtherMsg
的值在其method set中没有这样的方法,只有一个指向它的指针,即类型*OtherMsg
的值(因为OtherMsg.Id()
有指针接收器)。
要使其工作,请注册一个 *OtherMsg
:
gob.RegisterName("OtherMsg", &OtherMsg{})
或者简单地说:
gob.Register(&OtherMsg{})
查看 Go Playground 上的工作示例:
func init() {
gob.Register(&OtherMsg{})
}
func main() {
var m MyMessage = &OtherMsg{
MyMessageHeader: MyMessageHeader{
MessageId: 1,
OtherId: 2,
},
OtherField: "othervalue",
}
data, err := MarshalMessage(m)
if err != nil {
panic(err)
}
m2, err := UnmarshalMessage(data)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", m2)
}
输出(在 Go Playground 上尝试):
&{MyMessageHeader:{MessageId:1 OtherId:2} OtherField:othervalue}