在Go中,下列種類的類型的值可以有間接底層部分:
注意:此答案基于標準編譯器的實現(xiàn)。事實上,函數(shù)類型的值是否有間接底層部分是難以證明的。 另外,字符串和接口類型的值在邏輯上應(yīng)該被認為是不含間接底層部分。 請閱讀值部一文獲取更多信息。
len | cap | close | delete | make | |
---|---|---|---|---|---|
字符串值 | 可以 | ||||
數(shù)組或者數(shù)組指針值 | 可以 | 可以 | |||
切片值 | 可以 | 可以 | 可以 | ||
映射值 | 可以 | 可以 | 可以 | ||
通道值 | 可以 | 可以 | 可以 | 可以 |
可以被用做內(nèi)置函數(shù)len
調(diào)用的參數(shù)的值的類型都可以被稱為(廣義上的)容器類型。 這些容器類型的值都可以跟在for-range
循環(huán)的range
關(guān)鍵字后。
類型 | 容器值是否支持添加新的元素? | 容器值中的元素是否可以被替換? | 容器值中的元素是否可尋址? | 訪問容器值元素是否會更改容器長度? | 容器值是否可以有間接底層部分? |
---|---|---|---|---|---|
字符串 | 否 | 否 | 否 | 否 | 是(1) |
數(shù)組 | 否 | 是(2) | 是(2) | 否 | 否 |
切片 | 否(3) | 是 | 是 | 否 | 是 |
映射 | 是 | 是 | 否 | 否 | 是 |
通道 | 是(4) | 否 | 否 | 是 | 是 |
(1) 對于標準編譯器和運行時來說。
(2) 對于可尋址的數(shù)組值來說。
(3) 一般說來,一個切片的長度只能通過將另外一個切片賦值給它來被整體替換修改,這里我們不視這種情況為“添加新的元素”。 其實,切片的長度也可以通過調(diào)用reflect.SetLen
來單獨修改。增加切片的長度可以看作是一種變相的向切片添加元素。 但reflect.SetLen
函數(shù)的效率很低,因此很少使用。
(4) 對于帶緩沖并且緩沖未滿的通道來說。
下面在四種類型的值(除了切片和映射類型的零值)可以用組合字面量表示。
類型(T ) |
T{} 是類型T 的零值? |
---|---|
結(jié)構(gòu)體類型 | 是 |
數(shù)組類型 | 是 |
切片類型 | 否
(零值用 nil 表示) |
映射類型 | 否
(零值用 nil 表示) |
詳見值復(fù)制成本一文。
下面這些類型的零值可以用預(yù)聲明的nil
標識符表示。
類型(T ) |
T(nil) 的尺寸 |
---|---|
指針 | 1 word |
切片 | 3 words |
映射 | 1 word |
通道 | 1 word |
函數(shù) | 1 word |
接口 | 2 words |
上表列出的尺寸為標準編譯器的結(jié)果。 一個word(原生字)在32位的架構(gòu)中為4個字節(jié),在64位的架構(gòu)中為8個字節(jié)。 一個Go值的間接底層部分未統(tǒng)計在尺寸中。
一個類型的零值的尺寸和其它非零值的尺寸是一致的。
詳見方法一文。
詳見類型內(nèi)嵌一文。
如果一個函數(shù)調(diào)用在編譯時刻被估值,則估值結(jié)果為一個常量。
函數(shù) | 返回類型 | 其調(diào)用是否總是在編譯時刻估值? |
---|---|---|
unsafe.Sizeof | uintptr
|
是 |
unsafe.Alignof | ||
unsafe.Offsetof | ||
len |
int
|
否
Go語言白皮書中提到:
|
cap |
||
real |
默認類型為
float64
(結(jié)果為類型不確定值) |
否
|
imag |
||
complex | 默認類型為
complex128
(結(jié)果為類型不確定值) |
否
|
請閱讀此條問答獲取詳情。
請閱讀此條問答獲取詳情。
允許被聲明卻不使用? | |
---|---|
包引入 | 不允許 |
類型 | 允許 |
變量 | 包級全局變量允許,但局部變量不允許(對于官方標準編譯器)。 |
常量 | 允許 |
函數(shù) | 允許 |
跳轉(zhuǎn)標簽 | 不允許 |
下面這些同種類的代碼元素可多個被一起聲明在一對小括號()
中:
函數(shù)是不能多個被一起聲明在一對小括號()
中的。跳轉(zhuǎn)標簽也不能。
下面這些代碼元素的聲明既可以被聲明在函數(shù)內(nèi)也可以被聲明在函數(shù)外:
包引入必須被聲明在其它種類的代碼元素的聲明之前。
函數(shù)必須聲明在任何函數(shù)體之外。匿名函數(shù)可以定義在函數(shù)體內(nèi),但那不屬于聲明。
跳轉(zhuǎn)標簽必須聲明在函數(shù)體內(nèi)。
下列表達式的估值結(jié)果可以包含一個額外的可選的值:
語法 | 額外的可選的值(語法示例中的ok )的含義 |
舍棄額外的可選的值會對估值行為發(fā)生影響嗎? | |
---|---|---|---|
映射元素訪問 | e, ok = aMap[key]
|
鍵值key 對應(yīng)的條目是否存儲在映射值中 |
否 |
數(shù)據(jù)接收 | e, ok = <- aChannel
|
被接收到的值e 是否是在通道關(guān)閉之前發(fā)送的 |
否 |
類型斷言 | v, ok = anInterface.(T)
|
接口值的動態(tài)類型是否為類型T
|
是
(當可選的值被舍棄并且斷言失敗的時候,將產(chǎn)生一個恐慌。) |
無需引入任何包,我們可以使用下面幾種方法使當前協(xié)程永久阻塞:
make(chan struct{}) <- struct{}{}
// 或者
make(chan<- struct{}) <- struct{}{}
<-make(chan struct{})
// 或者
<-make(<-chan struct{})
// 或者
for range make(<-chan struct{}) {}
chan struct{}(nil) <- struct{}{}
// 或者
<-chan struct{}(nil)
// 或者
for range chan struct{}(nil) {}
select
流程控制代碼塊。
select{}
詳見字符串一文。
更多建議: