为了账号安全,请及时绑定邮箱和手机立即绑定

gob 解码结构中的接口与原始接口之间的区别

gob 解码结构中的接口与原始接口之间的区别

Go
子衿沉夜 2021-12-07 16:04:13
我一直在努力理解当接口类型嵌入到结构中时编码/解码与完全没有嵌入时的区别。使用以下示例:here in the playground注意代码声明了一个接口IFace。它声明了一个非导出的 struct impl。它设置了一些采空区的方法Register,GobEncode以及GobDecode该impl结构。然后,它还声明了一个Data导出的结构体,并且具有一个Foo接口类型的字段IFace。所以,有一个接口,一个实现它的结构,以及一个容器结构,它有一个值为该接口类型的字段。我的问题是容器结构Data愉快地通过 Gob 手套发送,并且当它通过时,它愉快地编码和解码结构中的 IFace 字段Data......太棒了!但是,我似乎无法通过 gob gauntlet 仅发送 IFace 值的一个实例。我缺少的魔法调用是什么?搜索错误消息给出了许多结果,但我相信我已经满足了 Gob 合同......并且“证明”在成功的 struct gobbing 中。显然我错过了一些东西,但看不到它。注意,程序的输出是:Encoding {IFace:bilbo} nowEncoding IFace:baggins nowDecoded {IFace:bilbo} nowdecode error: gob: local interface type *main.IFace can only be decoded from remote interface type; received concrete type implDecoded <nil> now实际代码是:package mainimport (    "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)    }
查看完整描述

1 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

电话

err = enc.Encode(baggins)

impl值传递给Encode. 它不传递类型的值IFace。文档http://research.swtch.com/interfaces可能有助于理解为什么会这样。该值被编码为具体类型impl

如果要解码为接口类型,则必须对接口类型进行编码。一种方法是传递一个指向接口值的指针:

err = enc.Encode(&baggins)

在这个调用中,a*IFace被传递给 Encode。解引用指针后,编码器看到该值是接口类型,并将其编码为接口类型。因为 gob 包在转换值时会执行所有必要的解引用和间接,所以在调用 Encode 时额外的间接级别不需要在解码时额外的间接级别。


查看完整回答
反对 回复 2021-12-07
  • 1 回答
  • 0 关注
  • 375 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信