This is a creation in Article, where the information may have evolved or changed.
Gob is a serialized encoding/decoding tool with a data structure that comes with the Golang package. Encoding uses encoder, decoding uses decoder. A typical application scenario is RPC (remote procedure calls).
Like GOB and JSON, the data structure is encoded by the sending side using encoder. After receiving the message, the receiving end uses decoder to change the cost of the serialized data variable.
One thing to note,
The structure of the sender and the structure of the receiving party do not need to be fully consistent
The default fields in the struct will not be sent. And on the receiving side, it is not necessary to have all the fields corresponding to the corresponding structural attributes. This example in Godoc is very image:
When the sender passes the value of the struct{a, B INT} structure, the receiver can allow the first 9 structures, but the latter 4 structures do not allow.
Personally, this setting is logical: The receiving end only accepts and sends the data structure " similar " to the data. Impersonation is allowed to be similar, but contradictions are not allowed.
Encoding and decoding rules for each type
Integer: Divided into sign int and usign int, which is also seen from the above example, int and uint cannot be decoded to each other. float and int are also not decoded to each other.
Struct,array,slice can be encoded. But function and channel cannot be encoded.
The bool type is encoded as a uint, and 0 is false,1 is true.
The value of a floating-point type is encoded as a value of type float64.
string and []byte Pass is the form of a uint (byte number) + byte[] Encoded
The slice and array are encoded in the form of UINT (array number) + each array encoding.
Maps is encoded in the form of a uint (map number) + key value
A struct is encoded according to a pair of pairs (attribute name + property value). Where the property value is its own corresponding GOB encoding. As I said earlier, if you have a property value of 0 or NULL, this property is ignored directly. The ordinal of each property is determined by the encoding time order, incrementing from 0. The struct will start with 1 for serialization before serialization, and 0 for the end of serialization. That is, the serialization of a struct is encoded according to the "-1 (0 attribute 1 name attribute 1 value) (1 attribute 2 name attribute 2 value) 0".
A very important point:
The attribute in a struct should be public, that is, it should start with an uppercase letter.
This can be accessed by a function outside the package!! (Thank you treapdb reminder)
Functions provided by Gob
Encode and Decode
For encoder and decoder you can look at this example:
Package Mainimport ("bytes" "Encoding/gob" "FMT" "Log") type P struct {x, Y, Z intname string}type Q struct {X, Y *int32na Me String}func Main () {var network bytes. Buffer ENC: = Gob. Newencoder (&network) Dec: = Gob. Newdecoder (&network)//Encode (send) the value.err: = Enc. Encode (P{3, 4, 5, "Pythagoras"}) if err! = Nil {log. Fatal ("Encode error:", err)}//Decode (receive) the Value.var q qerr = Dec. Decode (&Q) if err! = Nil {log. Fatal ("Decode error:", err)}fmt. PRINTLN (q) fmt. Printf ("%q: {%d,%d}\n", Q.name, *q.x, *Q.Y)}
All encoder and decoder constructors have an IO structure and need to develop which IO you will use to encode and decode the transmission.
There are several places to note in this code:
1 p and Q are two structures, which should be said to be "similar" to two structure bodies
2 encode is to pass the struct, but the decode function parameter is a pointer!
This is said in Godoc:
F E is nil, the value would be discarded. Otherwise, the value underlying e must is a pointer to the correct type for the next data item received.
If the decode parameter is not nil, then it must be a pointer.
3 If you pass encode into a pointer, that is
Func main () {var network bytes. Buffer //Stand-in for a network connectionenc: = Gob. Newencoder (&network)//would write to Network.dec: = Gob. Newdecoder (&network)//would read from network.//Encode (send) the value.err: = Enc. Encode (&p{3, 4, 5, "Pythagoras"}) if err! = Nil {log. Fatal ("Encode error:", err)}//Decode (receive) the Value.var q qerr = Dec. Decode (&Q) if err! = Nil {log. Fatal ("Decode error:", err)}fmt. PRINTLN (q) fmt. Printf ("%q: {%d,%d}\n", Q.name, *q.x, *Q.Y)}
This function is also not a problem.
Register and Registername
These two methods are required to register the possible types of interface{} when there is a field in the codec that is interface{}. Just look at the following example:
Package Mainimport ("bytes" "Encoding/gob" "FMT" "Log") type P struct {x, Y, Z intname interface{}}type Q struct {X, Y *in T32name interface{}}type Inner struct {Test int}func main () {var network bytes. Buffer //Stand-in for a network connectionenc: = Gob. Newencoder (&network)//would write to Network.dec: = Gob. Newdecoder (&network)//would read from Network.gob.Register (inner{})//Encode (send) the Value.inner: = Inner{1}err: = Enc. Encode (p{1,2,3, inner}) if err! = Nil {log. Fatal ("Encode error:", err)}//Decode (receive) the Value.var q qerr = Dec. Decode (&Q) if err! = Nil {log. Fatal ("Decode error:", err)}fmt. PRINTLN (q) fmt. Printf ("%q: {%d,%d}\n", Q.name, *q.x, *Q.Y)}
The gob is used here. Register (inner{}) tells the system: all interface are possible for the Inner structure.
In this example, if you comment on the gob. Register, the system will error.
The Registername is the same as the register, except that the register also has an alias for the type.
Gebencoder and Gobdecoder
This is two interfaces if your data structure implements both interfaces when calling encoder. The corresponding functions of these two structures are called when encode and Decoder.decode
Take a look at the following example:
Package Mainimport ("bytes" "Encoding/gob" "FMT" "Log") type P struct {X, Y, Z intname string}func (this *p) Gobencode () ( []byte, Error] { return []byte{},nil}type Q struct {X, Y *int32name string}func main () {var network bytes. Buffer ENC: = Gob. Newencoder (&network) Dec: = Gob. Newdecoder (&network)//Encode (send) the value.err: = Enc. Encode (P{3, 4, 5, "Pythagoras"}) if err! = Nil {log. Fatal ("Encode error:", err)}//Decode (receive) the Value.var q qerr = Dec. Decode (&Q) if err! = Nil {log. Fatal ("Decode error:", err)}fmt. PRINTLN (q) fmt. Printf ("%q: {%d,%d}\n", Q.name, *q.x, *Q.Y)}
Here my P implements the Gobencoder interface, so in Enc. Func (this *p) Gobencode ([]byte, error) is called when encode
Of course, this function directly returns an empty byte, so it will error when decoding: Decode Error:gob:type mismatch in decoder:want struct type main. Q; Got Non-struct
These two interfaces are exposed to make codec rules for the structure you define for yourself. Of course, if you use your own codec rules, the process of encoding and decoding needs to be a pair .
Postscript
The GOB package is a "private" codec provided by Golang, and the document says it will be more efficient than json,xml (although I have not verified it). Therefore, the communication between the two go services is advised not to use JSON, and it is possible to use GOB directly for data transfer.
Resources
Http://blog.golang.org/2011/03/gobs-of-data.html
http://www.mikespook.com/2011/03/%E3%80%90%E7%BF%BB%E8%AF%91%E3%80%91gob-%E7%9A%84%E6%95%B0%E6%8D%AE/