gpt4 book ai didi

go - gob 解码结构中的接口(interface)与原始解码之间的区别

转载 作者:IT王子 更新时间:2023-10-29 01:27:34 31 4
gpt4 key购买 nike

我一直在努力理解当该类型嵌入到结构中时与根本未嵌入时编码/解码接口(interface)类型之间的区别。

使用以下示例:here in the playground

注意代码声明了一个接口(interface)IFace。它声明了一个非导出结构 impl。它设置了一些 Gob 方法来 RegisterGobEncodeGobDecode impl 结构。

然后,它还声明了一个导出的结构Data,并且有一个接口(interface)类型为IFace 的字段Foo

所以,有一个接口(interface),一个实现它的结构,以及一个容器结构,它有一个值为该接口(interface)类型的字段。

我的问题是容器结构 Data 通过 Gob gauntlet 愉快地发送,并且,当它通过时,它愉快地编码和解码 Data 中的 IFace 字段> 结构...太棒了!但是,我似乎无法通过 gob gauntlet 发送一个 IFace 值的实例。

我缺少的魔法调用是什么?

搜索错误消息给出了一些结果,但我相信我已经满足了 Gob 契约(Contract)....并且成功的结构 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)

}

最佳答案

电话

err = enc.Encode(baggins)

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

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

err = enc.Encode(&baggins)

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

playground example

关于go - gob 解码结构中的接口(interface)与原始解码之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35006167/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com