arguments and results of remote procedure calls (RPCs) such as those provided by
package "rpc".
+The implementation compiles a custom codec for each data type in the stream and
+is most efficient when a single Encoder is used to transmit a stream of values,
+amortizing the cost of compilation.
+
+Basics
+
A stream of gobs is self-describing. Each data item in the stream is preceded by
a specification of its type, expressed in terms of a small set of predefined
types. Pointers are not transmitted, but the things they point to are
Decoder retrieves values from the encoded stream and unpacks them into local
variables.
+Types and Values
+
The source and destination values/types need not correspond exactly. For structs,
fields (identified by name) that are in the source but absent from the receiving
variable will be ignored. Fields that are in the receiving variable but missing
--- /dev/null
+// 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"
+)
+
+// The Vector type has unexported fields, which the package cannot access.
+// We therefore write a BinaryMarshal/BinaryUnmarshal method pair to allow us
+// to send and receive the type with the gob package. These interfaces are
+// defined in the "encoding" package.
+// We could equivalently use the locally defined GobEncode/GobDecoder
+// interfaces.
+type Vector struct {
+ x, y, z int
+}
+
+func (v Vector) MarshalBinary() ([]byte, error) {
+ // A simple encoding: plain text.
+ var b bytes.Buffer
+ fmt.Fprintln(&b, v.x, v.y, v.z)
+ return b.Bytes(), nil
+}
+
+// UnmarshalBinary modifies the receiver so it must take a pointer receiver.
+func (v *Vector) UnmarshalBinary(data []byte) error {
+ // A simple encoding: plain text.
+ b := bytes.NewBuffer(data)
+ _, err := fmt.Fscanln(b, &v.x, &v.y, &v.z)
+ return err
+}
+
+// This example transmits a value that implements the custom encoding and decoding methods.
+func Example_gob_encode_decode() {
+ var network bytes.Buffer // Stand-in for the network.
+
+ // Create an encoder and send a value.
+ enc := gob.NewEncoder(&network)
+ err := enc.Encode(Vector{3, 4, 5})
+ if err != nil {
+ log.Fatal("encode:", err)
+ }
+
+ // Create a decoder and receive a value.
+ dec := gob.NewDecoder(&network)
+ var v Vector
+ err = dec.Decode(&v)
+ if err != nil {
+ log.Fatal("decode:", err)
+ }
+ fmt.Println(v)
+
+ // Output:
+ // {3 4 5}
+}
--- /dev/null
+// 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
+}
--- /dev/null
+// 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"
+)
+
+type P struct {
+ X, Y, Z int
+ Name string
+}
+
+type Q struct {
+ X, Y *int32
+ Name string
+}
+
+// This example shows the basic usage of the package: Create an encoder,
+// transmit some values, receive them with a decoder.
+func Example_basic() {
+ // Initialize the encoder and decoder. Normally enc and dec would be
+ // bound to network connections and the encoder and decoder would
+ // run in different processes.
+ 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.
+
+ // Encode (send) some values.
+ err := enc.Encode(P{3, 4, 5, "Pythagoras"})
+ if err != nil {
+ log.Fatal("encode error:", err)
+ }
+ err = enc.Encode(P{1782, 1841, 1922, "Treehouse"})
+ if err != nil {
+ log.Fatal("encode error:", err)
+ }
+
+ // Decode (receive) and print the values.
+ var q Q
+ err = dec.Decode(&q)
+ if err != nil {
+ log.Fatal("decode error 1:", err)
+ }
+ fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)
+ err = dec.Decode(&q)
+ if err != nil {
+ log.Fatal("decode error 2:", err)
+ }
+ fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)
+
+ // Output:
+ // "Pythagoras": {3, 4}
+ // "Treehouse": {1782, 1841}
+}