读取将r中的结构化二进制数据读入数据。 数据必须是指向固定大小值或固定大小值切片的指针。 从r读取的字节使用指定的字节顺序进行解码,并写入数据的连续字段。 当解码布尔值时,零字节被解码为假,并且任何其他非零字节被解码为真。 读入结构时,将跳过具有空白(_)字段名称的字段的字段数据; 即,空白字段名称可用于填充。 读入结构时,必须导出所有非空白字段,否则“读取”可能会出现混乱。
但是这种只能使用固定大小类型的数据,变长数据就会异常,例如string, slice 等
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
type T struct {
A int64
B float64
}
func main() {
// Create a struct and write it.
t := T{A: 0xEEFFEEFF, B: 3.14}
buf := &bytes.Buffer{}
err := binary.Write(buf, binary.BigEndian, t)
if err != nil {
panic(err)
}
fmt.Println(buf.Bytes())
// Read into an empty struct.
t = T{}
err = binary.Read(buf, binary.BigEndian, &t)
if err != nil {
panic(err)
}
fmt.Printf("%x %f", t.A, t.B)
}
使用 unsafe 包
ByteToStruct
package main
import (
"fmt"
"unsafe"
)
type TestStructTobytes struct {
data int64
}
type SliceMock struct {
addr uintptr
len int
cap int
}
func main() {
var testStruct = &TestStructTobytes{100}
Len := unsafe.Sizeof(*testStruct)
testBytes := &SliceMock{
addr: uintptr(unsafe.Pointer(testStruct)),
cap: int(Len),
len: int(Len),
}
data := *(*[]byte)(unsafe.Pointer(testBytes))
fmt.Println("[]byte is : ", data)
var ptestStruct *TestStructTobytes = *(**TestStructTobytes)(unsafe.Pointer(&data))
fmt.Println("ptestStruct.data is : ", ptestStruct.data)
}
StructToByte
package main
import (
"fmt"
"unsafe"
)
type TestStructTobytes struct {
data int64
}
type SliceMock struct {
addr uintptr
len int
cap int
}
func main() {
var testStruct = &TestStructTobytes{100}
Len := unsafe.Sizeof(*testStruct)
testBytes := &SliceMock{
addr: uintptr(unsafe.Pointer(testStruct)),
cap: int(Len),
len: int(Len),
}
data := *(*[]byte)(unsafe.Pointer(testBytes))
fmt.Println("[]byte is : ", data)
}
只使用于客户端服务端都使用gob包进行编码和解码的情况。也就是客户端服务端都是go写的,不试用于多种语言。
Gob流不支持函数和通道。试图在最顶层编码这些类型的值会导致失败。结构体中包含函数或者通道类型的字段的话,会视作非导出字段(忽略)处理。
Gob可以编码任意实现了GobEncoder接口或者encoding.BinaryMarshaler接口的类型的值(通过调用对应的方法),GobEncoder接口优先。
Gob可以解码任意实现了GobDecoder接口或者encoding.BinaryUnmarshaler接口的类型的值(通过调用对应的方法),同样GobDecoder接口优先。
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
// A struct with a mix of fields, used for the GOB example.
type complexData struct {
N int
S string
M map[string]int
P []byte
C *complexData
E Addr
}
type Addr struct {
Comment string
}
func main() {
testStruct := complexData{
N: 23,
S: "string data",
M: map[string]int{"one": 1, "two": 2, "three": 3},
P: []byte("abc"),
C: &complexData{
N: 256,
S: "Recursive structs? Piece of cake!",
M: map[string]int{"01": 1, "10": 2, "11": 3},
E: Addr{
Comment: "InnerTest123123123123",
},
},
E: Addr{
Comment: "Test123123123",
},
}
fmt.Println("Outer complexData struct: ", testStruct)
fmt.Println("Inner complexData struct: ", testStruct.C)
fmt.Println("Inner complexData struct: ", testStruct.E)
fmt.Println("===========================")
var b bytes.Buffer
enc := gob.NewEncoder(&b)
err := enc.Encode(testStruct)
if err != nil {
fmt.Println(err)
}
dec := gob.NewDecoder(&b)
var data complexData
err = dec.Decode(&data)
if err != nil {
fmt.Println("Error decoding GOB data:", err)
return
}
fmt.Println("Outer complexData struct: ", data)
fmt.Println("Inner complexData struct: ", data.C)
fmt.Println("Inner complexData struct: ", testStruct.E)
}