關於golang中的切片詳解

2021-09-10 09:29:10 字數 1091 閱讀 1546

之前對切片的理解是本身是乙個指標,指標指向陣列,因為陣列是值賦值,所以陣列作為函式引數傳遞時,會被複製乙份,傳遞較大陣列時會比較浪費記憶體。

之前的理解部分對,但是瑕疵和錯誤的地方太多。

切片本身是乙個結構體,它是被golang封裝過的結構體,所以使用起來和陣列差不多,其結構體內容如下:

type slice struct {

array unsafe.pointer  // 指向陣列的指標,核心所在

len int                         // 切片長度,在長度範圍內,都可以像陣列那樣更新索引中的值,在len範圍外會報越界錯誤

cap int                       // 容量,指標所指向的陣列長度,必須大於等於len欄位

在len字段長度範圍的操作,和陣列用法一致,例如

var array [10]int

slice:=make(int,10,20)

slice[9]=10 // 在索引值小於10時,都可以直接進行賦值

array[9]=10

// fmt.println(slice[10])  // 輸出 panic: runtime error: index out of range,索引超出範圍之外了

fmt.println(slice[10])  // 輸出為5

len小於1000時,cap擴容兩倍,建立乙個2*cap長度的陣列,將之前陣列的內容賦值到新指標指向的陣列,len>1000時,擴容因子為1.25倍。

切片相當於對陣列的一層封裝,擴容方面比較靈活,陣列初始化以後陣列長度就再也不能變化了,想要擴容只能主動手寫函式。

在當函式引數進行值傳遞方面,slice維護了陣列的指標,加上本身的兩個int欄位,一共長24個位元組,作為值傳遞時比較輕量級,陣列值傳遞取決於陣列的長度,如果是1e6長度的int陣列,則每次傳遞需要重新開闢8m的記憶體建立乙個新的陣列,對空間浪費較大。

如果在函式傳入的引數是陣列指標,也只是需要占用8位元組的空間,乙個指標8位元組(64位系統),這時和使用slice沒有什麼區別,只是擴容的靈活度方面不如slice。

在不能確定切片的起始長度時,可以初始化為make(int,0,10)

golang 切片詳解

1.切片的定義 切片的結構定義在 reflect.sliceheader type sliceheader struct 看看切片的幾種定義方式 var a int nil切片,和nil相等,一般用來表示乙個不存在的切片 b int 空切片,和nil不相等,一般用來表示乙個空的集合 c int 有3...

golang 切片擷取引數方法詳解

以 s int為例 0.建議 做slice擷取時建議用兩個引數,尤其是從底層陣列進行切片操作時,因為這樣在進行第一次append操作時,會給切片重新分配空間,這樣減少切片對陣列的影響。1.結論 s s low high max 切片的三個引數的切片擷取的意義為 low為擷取的起始下標 含 high為...

golang 中奇怪的空切片

本文中介紹乙個奇怪現象,乙個空列表 或切片 卻可以列印出列表中的內容。以下 中,在乙個json字串中,定義乙個列表,列表中有乙個空字串。接著,將json字串解析到結構體中,最後,列印結構體中的字串列表。package main import fmt encoding json type host s...