在網路傳輸過程中,經常會這樣處理:socket接收到資料,先獲取其訊息頭,然後再做各種不同的業務處理。在解析訊息頭的時候的方法有多種多樣。其中最為高效解析訊息頭的方法就是直接把資料頭部分強制型別轉換為對應的訊息頭結構體。這種做法在c/c++中非常的常見。而golang其實也是可以這樣子做的。類似這樣的應用,直接型別轉換獲取訊息對應的解析方法其實效率會相對較高。
golang中struct和byte的轉換方法,其實就是用到了golang中的unsafe包加上型別轉換 , 約束:struct中不能有指標型別。
1、struct轉化為byte,轉換方法如下:
import (
"fmt"
"unsafe"
)type teststructtobytes struct
type slicemock struct
func main()
len := unsafe.sizeof(*teststruct)
testbytes := &slicemock
data := *(*byte)(unsafe.pointer(testbytes))
fmt.println("byte is : ", data)
}
執行結果:
byte
is : [10000
0000
0]
因為byte底層的資料結構為:
struct
其中addr為數值的位址,len為當地數值的長度,cap為數值的容量。
轉換的時候,需要定義乙個和byte底層結構一致的struct(如例子中的slicemock),然後把結構體的位址賦給addr,結構體的大小賦給len和cap。最後將其轉換為byte型別。
2、將byte轉換為struct,轉換方法如下:
import (
"fmt"
"unsafe"
)type teststructtobytes struct
type slicemock struct
func main()
len := unsafe.sizeof(*teststruct)
testbytes := &slicemock
data := *(*byte)(unsafe.pointer(testbytes))
fmt.println("byte is : ", data)
var pteststruct *teststructtobytes = *(**teststructtobytes)(unsafe.pointer(&data))
fmt.println("pteststruct.data is : ", pteststruct.data)
}
執行結果:
byte
is : [10000
0000
0]pteststruct.data is : 100
從上面的例子中將byte轉換為struct的**片段為:
var pteststruct *teststructtobytes = *(**teststructtobytes)(unsafe.pointer(&data))
分析:
由於在golang中編譯器不將byte視為指標,所以要使用其位址進行轉換,由於byte底層存放的是指向資料的位址。用byte的位址就需要使用雙層指標轉換,然後再指向其內容,得出來的就是轉換對應struct的指標了。
golang中json和struct的使用
在struct的字段後面加入json key 可以進行json格式輸出,其中key為json的鍵名 響應的結果為 1.如果struct的某個字段沒有傳值,則輸出的json為預設值,可以通過 omitempty 引數忽略掉值為空的鍵 type mydata struct data mydata suc...
Golang中的struct比較
可比較的資料型別除了上述三種外,還有boolean,complex,pointer,channel,inte ce和array 不可比較的資料型別包括,slice,map,和function 不包含不可比較的成員變數 reflect.deepequal函式,指標和例項均可以比較 無論有沒有包含不可比...
Golang中struct結構標籤 Tag 的使用
在看別人的一些 時,宣告結構時有個json name是做什麼用的?想知道原因得了解下 在golang中,命名都是推薦都是用駝峰方式,並且在首字母大小寫有特殊的語法含義 包外無法引用。但是由經常需要和其它的系統進行資料互動,例如轉成json格式,儲存到redis等等。這個時候如果直接用屬性名來作為鍵值...