我有一个未导出字段的结构,这些字段应该是gob编码和解码的。
可以这样说:
type A struct {
s int
}
func (a *A) Inc() {
a.s++
}显然,在这种情况下,我需要实现gob.GobEncoder和gob.GobDecoder接口。和,如果我直接使用这个结构,一切都可以很好地工作,
https://play.golang.org/p/dm3HwaI8eU
但是,我还需要一个实现相同逻辑并可序列化的接口:
type Incer interface {
gob.GobEncoder
gob.GobDecoder
Inc()
}完整代码: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接口的话,一切都会变得好起来.
我错过了什么重要的事情吗?因为描述的行为对我来说很奇怪
发布于 2017-04-10 14:42:47
问题在于,Incer接口实现了一个特定于encoding/gob包:gob.GobDecoder的特殊接口。
如果您的Incer接口只包含Inc()方法,它将工作,因为gob解码器看到您正在解码为接口类型,它将使用传输的类型解码该值,并在运行时检查解码后的值(其类型包含在流中并在流中传输)是否实现了目标接口类型,在这种情况下,它将:
type Incer interface {
Inc()
}所以解码成功了。
如果Incer接口还嵌入了gob.GobEncoder和gob.GobDecoder接口,那么它们就是-by定义--负责编码/解码。如果某个类型实现了这些接口,则解码器将不尝试使用所传输的类型对值进行解码,而是调用目标值的GobDecode()方法,在需要时创建一个零值。
因为您将一个nil值传递给Decoder.Decode(),所以解码器需要创建一个零值,但是它不知道要实例化什么类型,因为您传递的值是一个指向接口的指针。您不能创建接口类型的值,只能创建可能满足某些接口的具体类型的值。
您不能在您的gob.GobEncoder接口中包括gob.GobDecoder和Incer。我知道您希望确保实现它们,但是您可以看到-as--您将无法将它们解码为“通用”Incer接口值。而且,我甚至不认为有必要将它们包括在Incer中:gob.GobEncoder和gob.GobDecoder不是使它们可传输的唯一方法,还有由encoding/gob包检查的encoding.BinaryMarshaler和encoding.BinaryUnmarshaler。
发布于 2017-04-10 14:32:11
在您的情况下,您需要定义您期望解码转储到接口值的内存的“布局”是什么。当你宣布
var v Incer你没有给解码器任何关于解码必须怎么做的线索。如果您对解码器说您希望解码一个main.A .a struct,它可以使用您定义的方法(*A).GobEncode()和(*A).GobDecode():
var v Incer
v = &A{}https://stackoverflow.com/questions/43324919
复制相似问题