Ich habe gekämpft, um den Unterschied zwischen Kodierung/Dekodierung eines Schnittstellentyps zu verstehen, wenn dieser Typ in einer Struktur eingebettet ist, vs. wenn es überhaupt nicht eingebettet ist.Unterschied zwischen Gob Dekodierung einer Schnittstelle in einer Struktur, vs. rohe
Mit dem folgenden Beispiel: here in the playground
Hinweis erklärt der Code eine Schnittstelle IFace
. Es deklariert eine nicht exportierte Struktur impl
. Es richtet einige Gob-Methoden zu Register
, GobEncode
und GobDecode
die impl
Struktur ein.
Dann deklariert es auch eine Struktur Data
, die exportiert wird und ein einzelnes Feld Foo
hat, das vom Schnittstellentyp IFace
ist.
Also gibt es eine Schnittstelle, eine Struktur, die es implementiert, und eine Container-Struktur, die ein Feld hat, dessen Wert dieser Schnittstellentyp ist.
Mein Problem ist, dass die Container-Struktur Data
glücklich durch den Gob Gauntlet gesendet wird, und wenn es durchläuft, kodiert es glücklich und entschlüsselt das IFace-Feld in der Data
Struktur ... großartig! Aber ich kann nicht in der Lage sein, nur eine Instanz des IFace-Wertes durch den Gob Gauntlet zu senden.
Was ist die magische Invokation, die ich vermisse?
Die Suche nach der Fehlermeldung gibt eine Reihe von Ergebnissen, aber ich glaube, ich habe den GOB-Vertrag erfüllt .... und der "Beweis" davon ist in der erfolgreichen Struktur-Gobbing. Offensichtlich habe ich etwas übersehen, kann es aber nicht sehen.
Note, die Ausgabe des Programms ist:
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
Der tatsächliche Code ist:
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)
}
http: // Stackoverflow.com/questions/32428797/go-rpc-Aufruf-ist-fein-lokal-Marshalling-Problem-wenn-rpc verwenden/32430429 # 32430429 –
@JiangYD - dass Unmarshal-Methode ist für "Encoding/Json". Gibt es eine Entsprechung für 'encoding/gob'? – rolfl
https://golang.org/pkg/encoding/gob/#GobDecoder –