介紹
在平時做專案得時候,經常會看到很多包里面定義了結構體,
e.g. 在context
包里面Context
介面中的Done()
方法,Done()
回傳一個是以空結構體定義資料的通道chan struct{}
,那這里他是有什么特殊用意嗎?我們接下來分析struct{}
的作用,
struct{}
空結構是沒有欄位的結構型別,下面看示例:
type Demo struct{}
var demo struct{}
上面定義了一個Demo
的結構體,var 宣告變數demo
結構體,
width
在介紹空結構前,先來討論一下這個width
,
這里說的這個“width”來自于 gc 編譯器
,它描述型別實體占用的存盤位元組數(一個位元組=8位
),width
是型別的一個屬性,由于 Go
程式中的每個值都有一個型別,因此該值的width
由其型別定義,并且始終是 8 位的倍數
,
我們可以使用unsafe.Sizeof()
函式獲取任何值的width
:
var num int
var str string
fmt.Println(unsafe.Sizeof(num)) // output: 8
fmt.Println(unsafe.Sizeof(str)) // output: 16
陣列型別的width
是其元素型別的倍數:
var arr [3]uint32
fmt.Println(unsafe.Sizeof(arr))
結構體提供了一種更靈活的方式來定義復合型別,其width
是組成型別的width
加上填充的總和:
type Test struct {
num16 uint16
num32 uint32
}
var test Test
fmt.Println(unsafe.Sizeof(test)) // 列印 8,而不是 6
列印結果是8
,這個就和記憶體對齊有關系了,這里不作詳細的說明,
struct{}:
空結構體的位元組占用是多少呢,通過下面的例子列印得到結果:
var s struct{}
fmt.Println(unsafe.Sizeof(s)) // 列印 0
由于空結構體占用 零位元組
,因此它不需要任何的填充,所以,struct{}
空結構組成的結構也不會占用任何存盤空間,
type S struct {
A struct{}
B struct{}
}
var s S
fmt.Println(unsafe.Sizeof(s)) // 列印 0
使用場景
- 可以宣告一個陣列structs{},它們當然也是一樣不會占用存盤空間,
var arr [100000]struct{}
fmt.Println(unsafe.Sizeof(arr)) // 列印 0
- struct{}型別的
切片
只會占用其SliceHeader
的空間:
var arr = make([]struct{}, 1000000000)
fmt.Println(unsafe.Sizeof(arr)) // 列印 24
但是我們任然可以對這個切片正常操作:
var x = make([]struct{}, 100)
var y = x[:50]
fmt.Println(len(y), cap(y)) // 列印 50 100
- struct{}是可尋址時,也一樣可以獲取它的地址:
var test struct{}
var data = https://www.cnblogs.com/smallKilts/archive/2023/06/27/&test
當兩個不同變數相同資料型別的時候,他們兩個的地址是等的:
var a, b struct{}
fmt.Println(&a == &b) // true
但是下面兩個變數是不一樣的:
a := make([]struct{}, 10)
b := make([]struct{}, 20)
fmt.Println(&a == &b) // false, a 和 b 是不同的切片
fmt.Println(&a[0] == &b[0]) // true,它們的支持陣列是相同的
總結
所以通過上面的分析,空結構體在記憶體上不占用資源,因此,我們在開發的時候可以通過chan struct{}
來實作 go 協程之間信號的傳遞等用途,
轉載:風向閱讀 - Golang空結構體struct{}的作用?
地址:https://www.aiweimeng.top/archives/42.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556111.html
標籤:其他
下一篇:返回列表