1
0
mirror of https://github.com/golang/go synced 2024-11-25 01:57:56 -07:00

gob: when sending an interface value, indirect down to the

underlying type; otherwise encoding fails when sending
a pointer value.

R=rsc
CC=golang-dev
https://golang.org/cl/2922041
This commit is contained in:
Rob Pike 2010-11-05 10:36:27 -07:00
parent 836529a63c
commit 9f7f69d300
2 changed files with 39 additions and 2 deletions

View File

@ -1225,7 +1225,6 @@ func TestInterfaceBasic(t *testing.T) {
"hello", "hello",
[]byte("sailor"), []byte("sailor"),
} }
// Register the types.
err := NewEncoder(b).Encode(item1) err := NewEncoder(b).Encode(item1)
if err != nil { if err != nil {
t.Error("expected no encode error; got", err) t.Error("expected no encode error; got", err)
@ -1248,6 +1247,44 @@ func TestInterfaceBasic(t *testing.T) {
} }
} }
type String string
type PtrInterfaceItem struct {
str interface{} // basic
Str interface{} // derived
}
// We'll send pointers; should receive values.
// Also check that we can register T but send *T.
func TestInterfacePointer(t *testing.T) {
b := new(bytes.Buffer)
str1 := "howdy"
str2 := String("kiddo")
item1 := &PtrInterfaceItem{
&str1,
&str2,
}
// Register the type.
Register(str2)
err := NewEncoder(b).Encode(item1)
if err != nil {
t.Error("expected no encode error; got", err)
}
item2 := &PtrInterfaceItem{}
err = NewDecoder(b).Decode(&item2)
if err != nil {
t.Fatal("decode:", err)
}
// Hand test for correct types and values.
if v, ok := item2.str.(string); !ok || v != str1 {
t.Errorf("basic string failed: %q should be %q", v, str1)
}
if v, ok := item2.Str.(String); !ok || v != str2 {
t.Errorf("derived type String failed: %q should be %q", v, str2)
}
}
func TestIgnoreInterface(t *testing.T) { func TestIgnoreInterface(t *testing.T) {
iVal := Int(3) iVal := Int(3)
fVal := Float(5) fVal := Float(5)

View File

@ -404,7 +404,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue)
return return
} }
typ := iv.Elem().Type() typ, _ := indirect(iv.Elem().Type())
name, ok := concreteTypeToName[typ] name, ok := concreteTypeToName[typ]
if !ok { if !ok {
errorf("gob: type not registered for interface: %s", typ) errorf("gob: type not registered for interface: %s", typ)