6

インターフェイス型が構造体に埋め込まれている場合と、まったく埋め込まれていない場合のインターフェイス型のエンコード/デコードの違いを理解するのに苦労しています。

次の例を使用します

コードが interface を宣言していることに注意してくださいIFace。エクスポートされていない struct を宣言していimplます。RegisterGobEncode、およびstructGobDecodeにいくつかの Gob メソッドを設定します。impl

次に、エクスポートされる構造体も宣言し、インターフェース タイプのData単一フィールドを持ちます。FooIFace

したがって、インターフェース、それを実装する構造体、および値がそのインターフェース型であるフィールドを持つコンテナー構造体があります。

私の問題は、コンテナー構造体Dataが Gob gauntlet を介して問題なく送信され、それが通過すると、構造体の IFace フィールドを問題なくエンコードおよびデコードすることDataです...すばらしい! しかし、ゴブ ガントレットを介して IFace 値のインスタンスだけを送信することはできないようです。

私が見逃している魔法の呼び出しは何ですか?

エラーメッセージを検索すると多くの結果が得られますが、私はゴブ契約を満たしていると信じています....そしてその「証拠」は構造体のゴビングの成功にあります。明らかに私は何かを見逃していますが、それを見ることはできません。

プログラムの出力は次のとおりです。

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)

}
4

1 に答える 1