Go語言-型別中的一些小細節
阿新 • • 發佈:2018-12-03
把平時的一些筆記放上來,主要是一些比較小的問題,這裡是關於golang中的型別中需要記錄的小知識點。
常量
【1】可以是某些編譯器能計算出結果的表示式
- unsafe.Sizeof
- len
- cap
const {
ptrSize = unsafe.Sizeof(unintptr(0))
strSize = len("Hello")
}
【2】當常量的不指定型別和值,預設和上一行的常量的型別和值相同
const {
x uint6 = 120
y
s = "abc"
z
}
列舉
關鍵字:iota
const {
a = iota // 0 預設為0
b // 1 預設遞增1
c = 100 // 100 手動設定資料
d // 100
e = iota // 4 需要顯式呼叫iota,計算c、d的位置
d // 5
}
展開
- 變數和常量的區別:變數在執行時分配記憶體空間,常量通常會被編譯器在預處理階段直接展開,作為指令資料直接使用。數字常量不分配地址空間;
- 常量陷阱:不指定型別的常量可以給其他常量賦值,顯式指定值的常量不可以給其他常量賦值。
引用型別
特指:slice、map、chaneel
new和make的區別
- new按指定型別分配記憶體空間
- make按照一定的規則(建立函式或指令)構建目標,完成相關記憶體分配和屬性初始化
自定義型別
定義:使用type建立使用者的自定義型別,包括基於現有的基礎型別、結構體、函式建立新的型別。
注意:即使type指定了新的型別,只能表明有相同的資料結構,兩個型別間沒有任何關係,不能視作別名
未命名型別
具有相同宣告的未命名型別視作同一種類型
- 相同基型別的指標
- 相同元素型別和長度的陣列(array)
- 相同元素型別的切片(slice)
- 相同鍵值型別的字典(map)
- 相同操作型別和方向的通道(channel)
- 相同欄位序列的結構體,注意的是struct不相同也視作不同(struct)
- 相同簽名【引數和返回值相同】的函式(func)
- 具有相同方法集【方法名和方法簽名】的介面
未命名型別轉化規則:
- 所屬的型別相同
- 基礎型別相同,其中一個是未命名型別
- 資料型別相同,將雙向通道賦值給單向通道,且其中一個為未命名型別
- 將預設值nil賦值給切片、字典、通道、指標、函式、介面
- 物件實現了目標介面
指標型別
可以通過unsafe.Pointer轉換成uintptr進行指標加減法運算,但可能造成非法訪問。
【區別】
Pointer類似void* 的萬能指標,可用來轉換指標型別,void* 能安全持有物件成員,uintptr只是一種整數型別,不引用目標物件,無法阻止垃圾回收物件記憶體。
零長度物件地址
是否相等和版本實現有關,不等於nil,即使長度為0,物件依然合法存在,擁有合法的記憶體地址,和nil不一樣。在runtime/malloc.go中有個zerobase的全域性變數,通過mallocgc分配的0長度的物件都使用這個地址。在棧上分配,為呼叫mallocgc函式。