讀取將r中的結構化二進制數據讀入數據。 數據必須是指向固定大小值或固定大小值切片的指針。 從r讀取的字節使用指定的字節順序進行解碼,並寫入數據的連續字段。 當解碼布爾值時,零字節被解碼爲假,而且任何其餘非零字節被解碼爲真。 讀入結構時,將跳過具備空白(_)字段名稱的字段的字段數據; 即,空白字段名稱可用於填充。 讀入結構時,必須導出全部非空白字段,不然「讀取」可能會出現混亂。函數
可是這種只能使用固定大小類型的數據,變長數據就會異常,例如string, slice 等ui
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) }
StructToBytecode
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流不支持函數和通道。試圖在最頂層編碼這些類型的值會致使失敗。結構體中包含函數或者通道類型的字段的話,會視做非導出字段(忽略)處理。three
Gob能夠編碼任意實現了GobEncoder接口或者encoding.BinaryMarshaler接口的類型的值(經過調用對應的方法),GobEncoder接口優先。ip
Gob能夠解碼任意實現了GobDecoder接口或者encoding.BinaryUnmarshaler接口的類型的值(經過調用對應的方法),一樣GobDecoder接口優先。get
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) }
[譯]Go裏面的unsafe包詳解string