【发布时间】:2016-01-26 02:35:25
【问题描述】:
我一直在努力理解当接口类型嵌入到结构中时编码/解码接口类型与根本不嵌入时之间的区别。
使用以下示例:here in the playground
注意代码声明了一个接口IFace。它声明了一个非导出结构impl。它为Register、GobEncode 和GobDecode 和impl 结构设置了一些Gob 方法。
然后,它还声明了一个结构体Data,该结构体被导出,并且有一个Foo的字段Foo,它的接口类型为IFace。
所以,有一个接口,一个实现它的结构体,以及一个容器结构体,该结构体具有一个字段,其值为该接口类型。
我的问题是容器结构Data 很高兴通过 Gob 手套发送,并且当它通过时,它很高兴对Data 结构中的 IFace 字段进行编码和解码......太好了!但是,我似乎无法通过 gob gauntlet 仅发送 IFace 值的一个实例。
我缺少的魔法调用是什么?
搜索错误消息给出了许多结果,但我相信我已经满足了 Gob 合同......并且“证明”就是成功的 struct gobbing。显然我错过了一些东西,但看不到它。
注意,程序的输出是:
Encoding {IFace:bilbo} now
Encoding IFace:baggins now
Decoded {IFace:bilbo} now
decode error: gob: local interface type *main.IFace can only be decoded from remote interface type; received concrete type impl
Decoded <nil> now
实际代码是:
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
type IFace interface {
FooBar() string
}
type impl struct {
value string
}
func init() {
gob.Register(impl{})
}
func (i impl) FooBar() string {
return i.value
}
func (i impl) String() string {
return "IFace:" + i.value
}
func (i impl) GobEncode() ([]byte, error) {
return []byte(i.value), nil
}
func (i *impl) GobDecode(dat []byte) error {
val := string(dat)
i.value = val
return nil
}
func newIFace(val string) IFace {
return impl{val}
}
type Data struct {
Foo IFace
}
func main() {
var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network.
var err error
var bilbo IFace
bilbo = newIFace("bilbo")
var baggins IFace
baggins = newIFace("baggins")
dat := Data{bilbo}
fmt.Printf("Encoding %v now\n", dat)
err = enc.Encode(dat)
if err != nil {
fmt.Println("encode error:", err)
}
fmt.Printf("Encoding %v now\n", baggins)
err = enc.Encode(baggins)
if err != nil {
fmt.Println("encode error:", err)
}
var pdat Data
err = dec.Decode(&pdat)
if err != nil {
fmt.Println("decode error:", err)
}
fmt.Printf("Decoded %v now\n", pdat)
var pbag IFace
err = dec.Decode(&pbag)
if err != nil {
fmt.Println("decode error:", err)
}
fmt.Printf("Decoded %v now\n", pbag)
}
【问题讨论】:
-
@JiangYD - Unmarshal 方法适用于
encoding/json。encoding/gob是否有等价物? -
好的,@JiangYD - 我在问题中的代码是使用 GobDecoder 和 GobEncoder (当接口嵌入到结构中时它可以工作,但当接口是独立的时不能工作)。
-
这并没有破坏
the reflector knows the underlying type的问题。将接口更改为结构,并将动态类型嵌入到该结构中。