1. 程式人生 > >Go語言-型別中的一些小細節

Go語言-型別中的一些小細節

把平時的一些筆記放上來,主要是一些比較小的問題,這裡是關於golang中的型別中需要記錄的小知識點。

常量

【1】可以是某些編譯器能計算出結果的表示式

  1. unsafe.Sizeof
  2. len
  3. 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
}

展開

  1. 變數和常量的區別:變數在執行時分配記憶體空間,常量通常會被編譯器在預處理階段直接展開,作為指令資料直接使用。數字常量不分配地址空間;
  2. 常量陷阱:不指定型別的常量可以給其他常量賦值,顯式指定值的常量不可以給其他常量賦值。

引用型別

特指:slice、map、chaneel

new和make的區別
  1. new按指定型別分配記憶體空間
  2. make按照一定的規則(建立函式或指令)構建目標,完成相關記憶體分配和屬性初始化
自定義型別

定義:使用type建立使用者的自定義型別,包括基於現有的基礎型別、結構體、函式建立新的型別。

注意:即使type指定了新的型別,只能表明有相同的資料結構,兩個型別間沒有任何關係,不能視作別名

未命名型別

具有相同宣告的未命名型別視作同一種類型

  1. 相同基型別的指標
  2. 相同元素型別和長度的陣列(array)
  3. 相同元素型別的切片(slice)
  4. 相同鍵值型別的字典(map)
  5. 相同操作型別和方向的通道(channel)
  6. 相同欄位序列的結構體,注意的是struct不相同也視作不同(struct)
  7. 相同簽名【引數和返回值相同】的函式(func)
  8. 具有相同方法集【方法名和方法簽名】的介面

未命名型別轉化規則:

  1. 所屬的型別相同
  2. 基礎型別相同,其中一個是未命名型別
  3. 資料型別相同,將雙向通道賦值給單向通道,且其中一個為未命名型別
  4. 將預設值nil賦值給切片、字典、通道、指標、函式、介面
  5. 物件實現了目標介面

指標型別

可以通過unsafe.Pointer轉換成uintptr進行指標加減法運算,但可能造成非法訪問。

【區別】

Pointer類似void* 的萬能指標,可用來轉換指標型別,void* 能安全持有物件成員,uintptr只是一種整數型別,不引用目標物件,無法阻止垃圾回收物件記憶體。

零長度物件地址

是否相等和版本實現有關,不等於nil,即使長度為0,物件依然合法存在,擁有合法的記憶體地址,和nil不一樣。在runtime/malloc.go中有個zerobase的全域性變數,通過mallocgc分配的0長度的物件都使用這個地址。在棧上分配,為呼叫mallocgc函式。