標籤:ima 注意 github 別名 src 種類 cannot 利用 pre
在記憶體中的形式
首先看一下在go中,一些基礎類型在記憶體中是以什麼形態存在的,如所示:
變數j的類型是int32, 而變數i的類型是int,兩者不是同一個類型,所以賦值操作i=j是一種類型錯誤cannot use j (type int32) as type int in assignment。
正確的方式應該是
i := int(7)j := int32(7)i = int(j)
結構體的域在記憶體中是緊密排列的。
靜態類型和底層類型
byte是Go的靜態類型,uint8是Go的底層類型
rune是int32的別名,用於表示unicode字元。通常在處理中文的時候需要用到它
string類型
定義在go-1.8.3/go/src/runtime/string.go
type stringStruct struct { str unsafe.Pointer len int}
兩個屬性:一個指標,一個int型的長度,都是私人成員!
string類型類型在Go語言的記憶體模型中用一個2字長的資料結構表示。 從可以看出,其實多個string是共用一個儲存的。
str[i:j]進行字串切片操作,會得到一個新的type stringStruct struct對象,該對象的指標依然還是指向str的底層儲存,長度為j-i。 這說明字串切分不涉及記憶體配置或複製操作,其效率等同於傳遞下標。
內建函數len()對string類型的操作是直接從底層結構中取出len值,而不需要額外的操作
slice類型
定義在/go-1.8.3/src/runtime/slice.go
type slice struct {array unsafe.Pointerlen intcap int}
顯然,type slice struct和上面的type stringStruct struct很類似,只是多了一個cap屬性。
一個slice是一個底層數組的部分引用。同理,對底層資料進行切片操作也不會涉及到記憶體配置或複製操作,僅僅是建立了一個type slice struct對象而已!
需要注意的是,在中,y[0:4]是有效,列印出來的結果會是[3,5,7,11]
由於slice是不同於指標的多字長結構,分割操作並不需要分配記憶體,甚至沒有通常被儲存在堆中的slice頭部。這種表示方法使slice操作和在C中傳遞指標、長度對一樣廉價。
slice相關的函數有如下幾個,是不是感覺很熟悉。
func makeslice(et *_type, len64, cap64 int64) slicefunc growslice(et *_type, old slice, cap int) slice func slicecopy(to, fm slice, width uintptr) intfunc slicestringcopy(to []byte, fm string) int
slice的擴容
對slice進行append操作時,可能會造成擴容操作。擴容規則如下:
- 如果新的大小是當前大小2倍以上,則大小增長為新大小
- 否則迴圈以下操作:如果當前長度len小於1024,按每次2倍增長,否則每次按當前cap的1/4增長。直到增長的大小超過或等於新大小。
newcap := old.capdoublecap := newcap + newcap//和old.cap的double進行比較if cap > doublecap {newcap = cap} else {if old.len < 1024 {newcap = doublecap} else {for newcap < cap {newcap += newcap / 4}}}slice與unsafe.Pointer相互轉換
- 利用make+slice弄塊記憶體出來自己管理。。。。這個比較牛逼了
s := make([]byte, 200)ptr := unsafe.Pointer(&s[0])
- 基於記憶體指標ptr構造出一個slice
var o []bytesliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&o)))sliceHeader.Cap = lengthsliceHeader.Len = lengthsliceHeader.Data = uintptr(ptr)
new和make
瞭解完Go對type slice struct的定義之後,再來理解new和make的差異就簡單得多了。
- new(T),僅分配記憶體,不進行初始化。返回的
*T指向一個類型T的零值。
- make(T, args),分配記憶體,且進行初始化。返回是
T本身。因為T本身就是一個參考型別。
以下屬聲明的類型為例子,分別用new和make的效果如:
type Point struct { X, Y int }type Rect1 struct { Min, Max Point }type Rect2 struct { Min, Max *Point }
原文: https://github.com/Kevin-fqh/learning-k8s-source-code/blob/master/%E6%B7%B1%E5%85%A5go/(01)%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B.md
Go語言 基本類型