From 9f7f69d3002e585ace16c868d3cbf62f4d1203d6 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 5 Nov 2010 10:36:27 -0700 Subject: [PATCH] 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 --- src/pkg/gob/codec_test.go | 39 ++++++++++++++++++++++++++++++++++++++- src/pkg/gob/encode.go | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/pkg/gob/codec_test.go b/src/pkg/gob/codec_test.go index 426cc80edf3..a95cfa9929b 100644 --- a/src/pkg/gob/codec_test.go +++ b/src/pkg/gob/codec_test.go @@ -1225,7 +1225,6 @@ func TestInterfaceBasic(t *testing.T) { "hello", []byte("sailor"), } - // Register the types. err := NewEncoder(b).Encode(item1) if err != nil { 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) { iVal := Int(3) fVal := Float(5) diff --git a/src/pkg/gob/encode.go b/src/pkg/gob/encode.go index 694cddbcc90..73938668020 100644 --- a/src/pkg/gob/encode.go +++ b/src/pkg/gob/encode.go @@ -404,7 +404,7 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) return } - typ := iv.Elem().Type() + typ, _ := indirect(iv.Elem().Type()) name, ok := concreteTypeToName[typ] if !ok { errorf("gob: type not registered for interface: %s", typ)