go語言sizeof Go語言中文網(wǎng)

GoLang內(nèi)建類型 int 占多少字節(jié)

int is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for, say, int32.

站在用戶的角度思考問題,與客戶深入溝通,找到綦江網(wǎng)站設(shè)計與綦江網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名申請、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋綦江地區(qū)。

int 是帶符號整數(shù)類型,其大小至少為32位。 它是一種確切的類型,而不是 int32 的別名。

int 不是int32,那 int 在內(nèi)存站多少字節(jié)呢?官方?jīng)]有明確,讓我們測試下。

GOARCH="amd64"

package main

import (

"fmt"

"unsafe"

)

func main() {

i := int(1)

fmt.Println(unsafe.Sizeof(i)) // 4

j := 1

fmt.Println(unsafe.Sizeof(j)) // 4

u := uint(1)

fmt.Println(unsafe.Sizeof(u)) // 4

}

可以認(rèn)為 int 是4字節(jié)么?我不敢這樣認(rèn)為,GoLang支持多種平臺架構(gòu)。如果對size有明確要求,那就用 int32 之類的吧。

補充:隨Go版本的變化,這個的確是在變化,所以到底占用多少字節(jié),還是看具體版本吧

Go語言中的字節(jié)序

Go中的binary包實現(xiàn)了簡單的數(shù)字與字節(jié)序列的轉(zhuǎn)換以及變長值的編解碼

package main

import ( "fmt" "bytes" "encoding/binary" ) func main(){ n := 0x12345678 bytesBuffer := bytes.NewBuffer([]byte{}) //BigEndian 大端順序存儲 LittleEndian小端順序存儲 binary.Write(bytesBuffer, binary.BigEndian, int32(n)) data:=bytesBuffer.Bytes() fmt.Printf("[0]: %#x addr:%#x\n",data[0],data[0]) fmt.Printf("[0]: %#x addr:%#x\n",data[1],data[1]) fmt.Printf("[0]: %#x addr:%#x\n",data[2],data[2]) fmt.Printf("[0]: %#x addr:%#x\n",data[3],data[3]) }

輸出

[0]: 0x12 addr:0xc042010248 [1]: 0x34 addr:0xc042010249 [2]: 0x56 addr:0xc04201024a [3]: 0x78 addr:0xc04201024b

也可以使用下面的方式

n := 0x12345678 var data []byte = make([]byte,4) //操作的都是無符號整型 binary.BigEndian.PutUint32(data,uint32(n))

可以使用下面的方式判斷當(dāng)前系統(tǒng)的字節(jié)序類型

const INT_SIZE int = int(unsafe.Sizeof(0))

//判斷我們系統(tǒng)中的字節(jié)序類型 func systemEdian() { var i int = 0x1 bs := (*[INT_SIZE]byte)(unsafe.Pointer(i)) if bs[0] == 0 { fmt.Println("system edian is little endian") } else { fmt.Println("system edian is big endian") } }

golang 結(jié)構(gòu)體 字節(jié)對齊是怎么樣的

用golang解析二進制協(xié)議時,其實沒必要管結(jié)構(gòu)體的字段的對齊規(guī)則,何況語言規(guī)范也沒有規(guī)定如何對齊,也就是沒有規(guī)則。用encoding/binary.Read函數(shù)直接讀入struct里就行,struct就像c那樣寫

type Data struct {

Size, MsgType uint16

Sequence uint32

// ...

}

golang編譯器加不加padding,Read都能正常工作,runtime知道Data的布局的,不像C直接做cast所以要知道怎樣對齊。

用unsafe.Alignof可以知道每個field的對齊長度,但沒必要用到。

package main

/*

#include stdint.h

#pragma pack(push, 1)

typedef struct {

uint16_t size;

uint16_t msgtype;

uint32_t sequnce;

uint8_t data1;

uint32_t data2;

uint16_t data3;

} mydata;

#pragma pack(pop)

mydata foo = {

1, 2, 3, 4, 5, 6,

};

int size() {

return sizeof(mydata);

}

*/

import "C"

import (

"bytes"

"encoding/binary"

"fmt"

"log"

"unsafe"

)

func main() {

bs := C.GoBytes(unsafe.Pointer(C.foo), C.size())

fmt.Printf("len %d data %v\n", len(bs), bs)

var data struct {

Size, Msytype uint16

Sequence uint32

Data1 uint8

Data2 uint32

Data3 uint16

}

err := binary.Read(bytes.NewReader(bs), binary.LittleEndian, data)

if err != nil {

log.Fatal(err)

}

fmt.Printf("%v\n", data) // {1 2 3 4 5 6}

buf := new(bytes.Buffer)

binary.Write(buf, binary.BigEndian, data)

fmt.Printf("%d %v\n", buf.Len(), buf.Bytes()) // 15 [0 1 0 2 0 0 0 3 4 0 0 0 5 0 6]

}

Go 空結(jié)構(gòu)體 struct{} 的使用

struct是Go中的關(guān)鍵字,用于定義結(jié)構(gòu)類型。

例如:

struct {}是一個無元素的結(jié)構(gòu)體類型,通常在沒有信息存儲時使用。優(yōu)點是大小為0,不需要內(nèi)存來存儲struct {}類型的值。

struct {} {}是一個復(fù)合字面量,它構(gòu)造了一個struct {}類型的值,該值也是空。

go中可以使用 unsafe.Sizeof 計算出一個數(shù)據(jù)類型實例需要占用的字節(jié)數(shù)。我們驗證一下:

也就是說空結(jié)構(gòu)體實例不占用任何內(nèi)存空間。

Go 語言標(biāo)準(zhǔn)庫沒有提供 Set 的實現(xiàn),通常使用 map 來代替。事實上,對于集合來說,只需要 map 的鍵,而不需要值。

聲明為聲明為 map[string]struct{} ,由于struct{}是空,不關(guān)心內(nèi)容,這樣map便改造為set 。

map可以通過“comma ok”機制來獲取該key是否存在,例如 _, ok := map["key"] ,如果沒有對應(yīng)的值,ok為false。可以通過定義成 map[string]struct{} 的形式,值不再占用內(nèi)存。其值僅有兩種狀態(tài),有或無。如果定義的是 map[string]bool ,則結(jié)果有true、false或沒有三種狀態(tài),而且即使是將值設(shè)置為 bool 類型,也會多占據(jù) 1 個字節(jié)。因此呢,將 map 作為集合(Set)使用時,可以將值類型定義為空結(jié)構(gòu)體,僅作為占位符使用即可。

基于channels發(fā)送消息有兩個重要方面:發(fā)了消息、發(fā)了什么消息。一個強調(diào)了通訊的發(fā)生,一個強調(diào)了通訊的內(nèi)容。當(dāng)我們更希望強調(diào)通訊發(fā)生的時刻時,我們將它稱為 消息事件 。有些消息事件并不攜帶額外的信息,它僅僅是用作兩個goroutine之間的同步,這時候我們可以用 struct{} 空結(jié)構(gòu)體作為channels元素的類型。用來通知子協(xié)程(goroutine)執(zhí)行任務(wù),或只用來控制協(xié)程并發(fā)度。

在部分場景下,結(jié)構(gòu)體只包含方法,不包含任何的字段。這時候我們就可以使用空結(jié)構(gòu)體。

其實,上面的calculateInt 可以是任何類型,如 type calculateInt bool ,但是struct{}不占用任何空間,邏輯上也更合理,因此還是它最好。

標(biāo)題名稱:go語言sizeof Go語言中文網(wǎng)
文章URL:http://bm7419.com/article42/ddejiec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣關(guān)鍵詞優(yōu)化、網(wǎng)站導(dǎo)航、手機網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)站設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)