インターフェイス型が構造体に埋め込まれている場合と、まったく埋め込まれていない場合のインターフェイス型のエンコード/デコードの違いを理解するのに苦労しています。
次の例を使用します。
コードが interface を宣言していることに注意してくださいIFace
。エクスポートされていない struct を宣言していimpl
ます。Register
、GobEncode
、およびstructGobDecode
にいくつかの Gob メソッドを設定します。impl
次に、エクスポートされる構造体も宣言し、インターフェース タイプのData
単一フィールドを持ちます。Foo
IFace
したがって、インターフェース、それを実装する構造体、および値がそのインターフェース型であるフィールドを持つコンテナー構造体があります。
私の問題は、コンテナー構造体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)
}