| // Copyright 2013 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package gob_test | |
| import ( | |
| "bytes" | |
| "encoding/gob" | |
| "fmt" | |
| "log" | |
| "math" | |
| ) | |
| type Point struct { | |
| X, Y int | |
| } | |
| func (p Point) Hypotenuse() float64 { | |
| return math.Hypot(float64(p.X), float64(p.Y)) | |
| } | |
| type Pythagoras interface { | |
| Hypotenuse() float64 | |
| } | |
| // This example shows how to encode an interface value. The key | |
| // distinction from regular types is to register the concrete type that | |
| // implements the interface. | |
| func Example_interface() { | |
| var network bytes.Buffer // Stand-in for the network. | |
| // We must register the concrete type for the encoder and decoder (which would | |
| // normally be on a separate machine from the encoder). On each end, this tells the | |
| // engine which concrete type is being sent that implements the interface. | |
| gob.Register(Point{}) | |
| // Create an encoder and send some values. | |
| enc := gob.NewEncoder(&network) | |
| for i := 1; i <= 3; i++ { | |
| interfaceEncode(enc, Point{3 * i, 4 * i}) | |
| } | |
| // Create a decoder and receive some values. | |
| dec := gob.NewDecoder(&network) | |
| for i := 1; i <= 3; i++ { | |
| result := interfaceDecode(dec) | |
| fmt.Println(result.Hypotenuse()) | |
| } | |
| // Output: | |
| // 5 | |
| // 10 | |
| // 15 | |
| } | |
| // interfaceEncode encodes the interface value into the encoder. | |
| func interfaceEncode(enc *gob.Encoder, p Pythagoras) { | |
| // The encode will fail unless the concrete type has been | |
| // registered. We registered it in the calling function. | |
| // Pass pointer to interface so Encode sees (and hence sends) a value of | |
| // interface type. If we passed p directly it would see the concrete type instead. | |
| // See the blog post, "The Laws of Reflection" for background. | |
| err := enc.Encode(&p) | |
| if err != nil { | |
| log.Fatal("encode:", err) | |
| } | |
| } | |
| // interfaceDecode decodes the next interface value from the stream and returns it. | |
| func interfaceDecode(dec *gob.Decoder) Pythagoras { | |
| // The decode will fail unless the concrete type on the wire has been | |
| // registered. We registered it in the calling function. | |
| var p Pythagoras | |
| err := dec.Decode(&p) | |
| if err != nil { | |
| log.Fatal("decode:", err) | |
| } | |
| return p | |
| } | |