owned this note changed 5 years ago
Linked with GitHub

Go Go Power Slice! - Yu-Lang Chu

tags: COSCUP2020 入門 TR214

歡迎來到 https://hackmd.io/@coscup/2020 共筆

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

點擊本頁上方的 開始用 Markdown 一起寫筆記!
手機版請點選上方 按鈕展開議程列表。

請從這裡開始

Array and slice

The length is a part of the array's type

go spec

Slice 的定義:敘述底層的 array
要操作的是底層的 Array ,為何還需要 slice ?

Slice 包含一個指向 array 的指標與一個長度、容量
Slice 的長度跟底層 Array 沒有直接掛勾

type slice struct {
    array unsafe.Pointer
    len int
    cap int
}

array 賦值是 copy 而不是 reference

Append behind

append 到 slice ,底層的 array 可能產生變動

slice 是 pass by value 還是 call by value
slice 傳入 function 實會 copy 新的 slice,但是會 copy 指針(指向同樣的 array)
slice 可能是指向 array ,或是 array 的一部分

Compare

deep comapre 效能不太好

difference with other languages

  1. Go slice 可自由控制長度與容量

    • 可以把清理一到後面,容易自由安排清空記憶體的時間(可以先改變可見範圍,之後再移除或覆蓋)
    • 可能會有 memory leak
    • ​​​​​​a = a[:len(a)-2] 
      
  2. nil slice is just a zero length/cap slice and what the difference with empty slice

    • 沒有必要對 nil slice 作長度和容量檢查,可以當成一般 slice 操作

append

擴容流程:

  • 計算未來需要容量
  • 若不夠就擴容
  • 依據 slice 容量而非底層 array

String 可以直接附加到 byte slice

擴容策略:

  • 新容量大於 2 倍:直接變新容量
  • 否則作邏輯判斷
    • 變成 1.25 倍

Beavior of slice

Slice 長度 == 容量時作 append ,會進行擴容,同時創造新的 array

Common mistake

Memory leak

單純改變 Slice 長度卻沒有清空

  • 若 Slice 馬上被消滅不會有問題(自動 GC)
  • 存活時間長時需要手動清除

Append overwrites value(state slice )

mistake:

s1 := []byte{"dir1"}

s2 := s1[:len(s1) - 1]
s2 = append(s2, "3")

fmt.Printf("%q %q", s1, s2)
// dir3, dir3
s1 := []byte["dir"]

s2 := make([]byte, len(s1)-1)
copy()

Performance tips

  • allocate enough memory
  • Use append to reduce

allocate enough memory

assign 足夠容量:使用 append 時不會產生新 array

Make-Copy vs append

  • 都會作 copy
  • append 會有條件的作 copy
    • 減少記憶體額外操作

Reuse allocated memory :清空的方法

  1. 函式回傳相同長度 slice
  2. 把長度歸 0

implemenetation of queue

成長到一定長度就需要 new 新的 array

String & Byte

String 本質上是 Byte Slice

合法操作:

  • 直接 string append 到 Byte slice
  • string copy 到 slice

額外發現:直接用 String 比 Byte Slice 快(因為轉型需要花時間)

結論:不要一直轉形,因為會一直建立和毀滅 array

Select a repo