...

Source file src/encoding/gob/example_interface_test.go

Documentation: encoding/gob

		 1  // Copyright 2013 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package gob_test
		 6  
		 7  import (
		 8  	"bytes"
		 9  	"encoding/gob"
		10  	"fmt"
		11  	"log"
		12  	"math"
		13  )
		14  
		15  type Point struct {
		16  	X, Y int
		17  }
		18  
		19  func (p Point) Hypotenuse() float64 {
		20  	return math.Hypot(float64(p.X), float64(p.Y))
		21  }
		22  
		23  type Pythagoras interface {
		24  	Hypotenuse() float64
		25  }
		26  
		27  // This example shows how to encode an interface value. The key
		28  // distinction from regular types is to register the concrete type that
		29  // implements the interface.
		30  func Example_interface() {
		31  	var network bytes.Buffer // Stand-in for the network.
		32  
		33  	// We must register the concrete type for the encoder and decoder (which would
		34  	// normally be on a separate machine from the encoder). On each end, this tells the
		35  	// engine which concrete type is being sent that implements the interface.
		36  	gob.Register(Point{})
		37  
		38  	// Create an encoder and send some values.
		39  	enc := gob.NewEncoder(&network)
		40  	for i := 1; i <= 3; i++ {
		41  		interfaceEncode(enc, Point{3 * i, 4 * i})
		42  	}
		43  
		44  	// Create a decoder and receive some values.
		45  	dec := gob.NewDecoder(&network)
		46  	for i := 1; i <= 3; i++ {
		47  		result := interfaceDecode(dec)
		48  		fmt.Println(result.Hypotenuse())
		49  	}
		50  
		51  	// Output:
		52  	// 5
		53  	// 10
		54  	// 15
		55  }
		56  
		57  // interfaceEncode encodes the interface value into the encoder.
		58  func interfaceEncode(enc *gob.Encoder, p Pythagoras) {
		59  	// The encode will fail unless the concrete type has been
		60  	// registered. We registered it in the calling function.
		61  
		62  	// Pass pointer to interface so Encode sees (and hence sends) a value of
		63  	// interface type. If we passed p directly it would see the concrete type instead.
		64  	// See the blog post, "The Laws of Reflection" for background.
		65  	err := enc.Encode(&p)
		66  	if err != nil {
		67  		log.Fatal("encode:", err)
		68  	}
		69  }
		70  
		71  // interfaceDecode decodes the next interface value from the stream and returns it.
		72  func interfaceDecode(dec *gob.Decoder) Pythagoras {
		73  	// The decode will fail unless the concrete type on the wire has been
		74  	// registered. We registered it in the calling function.
		75  	var p Pythagoras
		76  	err := dec.Decode(&p)
		77  	if err != nil {
		78  		log.Fatal("decode:", err)
		79  	}
		80  	return p
		81  }
		82  

View as plain text