我有一个带有未导出字段的结构,应该对其进行 gob 编码和解码。
Say:
type A struct {
s int
}
func (a *A) Inc() {
a.s++
}
显然在这种情况下我需要实施gob.GobEncoder
and gob.GobDecoder
接口。和如果我直接使用该结构,一切正常:
https://play.golang.org/p/dm3HwaI8eU https://play.golang.org/p/dm3HwaI8eU
但我还需要一个实现相同逻辑并且可序列化的接口:
type Incer interface {
gob.GobEncoder
gob.GobDecoder
Inc()
}
完整代码:https://play.golang.org/p/Zig2mPrnrq https://play.golang.org/p/Zig2mPrnrq
突然它恐慌了:
panic: interface conversion: interface is nil, not gob.GobDecoder [recovered]
panic: interface conversion: interface is nil, not gob.GobDecoder
但如果我评论 gob 接口,一切都会变得很好。
我错过了什么重要的事情吗?因为所描述的行为对我来说似乎很奇怪
问题在于,Incer
接口实现了一个特殊的接口,特殊的encoding/gob
包裹:gob.GobDecoder
.
If your Incer
接口只包含Inc()
方法,它会起作用,因为 gob 解码器看到您正在解码为接口类型,并且它将使用传输的类型来解码该值并在运行时检查解码的值(其类型包含在流中并在流中传输)是否实现目标接口类型,在这种情况下它将:
type Incer interface {
Inc()
}
这样解码就成功了。
If the Incer
接口还嵌入了gob.GobEncoder
and gob.GobDecoder
接口,根据定义,它们负责编码/解码。如果某个类型实现了这些接口,则解码器将不会尝试使用传输的类型来解码该值,而是会调用GobDecode()
目标值的方法,如果需要则创建零值。
既然你通过了nil
价值Decoder.Decode()
,解码器需要创建一个零值,但它不知道要实例化什么类型,因为您传递的值是指向接口的指针。您不能创建接口类型的值,只能创建 a 的值concrete可以满足某些接口的类型。
你不能包括gob.GobEncoder
and gob.GobDecoder
在你的Incer
界面。我知道您想确保实现确实实现了它们,但是随后 - 正如您所看到的 - 您将无法将它们解码为“通用”Incer
接口值。而且我什至不认为有必要将它们包括在内Incer
: gob.GobEncoder
and gob.GobDecoder
并不是使它们可传播的唯一方法,还有encoding.BinaryMarshaler https://golang.org/pkg/encoding/#BinaryMarshaler and encoding.BinaryUnmarshaler https://golang.org/pkg/encoding/#BinaryUnmarshaler经检查的encoding/gob
包裹。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)