今天問題問的很基礎,考察了很多概念性問題,有些沒有答上來,自己做一下筆記
Q1:Golang裡哪些是實值型別,哪些是參考型別
A1:Golang中只有三種參考型別:slice(切片)、map(字典)、channel(管道);
關聯知識:slice用法和本質:
轉自:https://studygolang.com/articles/5877、
數組
Go的切片是在數組之上的抽象資料類型,因此在瞭解切片之前必須要要理解數組。
數群組類型由指定和長度和元素類型定義。例如,
[4]int 類型表示一個四個整數的序列。數組的長度是固定的,長度是數群組類型的一部分(int[4] 和 [5]int 是完全不同的類型)。
數組可以以常規的索引方式訪問,運算式 s[n] 訪問數組的第n 個元素。
數組不需要顯式的初始化;數組元素會自動初始化為零值:
切片
數組雖然有適用它們的地方,但是數組不夠靈活,因此在Go代碼中數組使用的並不多。但是,切片則使用得相當廣泛。切片基於數組構建,但是提供更強的功能和便利。
切片的類型是 []T,T 是切片元素的類型。
和數組不同的是,切片沒有固定的長度。
切片的本質
一個切片是一個數組切割區間的描述。它包含了指向數組的指標,切割區間的長度,和容量(切割區間的最大長度)。
可能的“陷阱”
正如前面所說,切片操作並不會複製底層的數組。此層的數組將被儲存在記憶體中,知道它不再被引用。有時候可能會因為一個小的記憶體引用導致儲存所有的資料。
例如,FindDigits 函數載入整個檔案到記憶體,然後搜尋第一個連續的數字,最後結果以切片方式返回。
var digitRegexp = regexp.MustCompile("[0-9]+")func FindDigits(filename string) []byte { b, _ := ioutil.ReadFile(filename) return digitRegexp.Find(b)}
這段代碼的行為和廣告類似,返回的 []byte 指向儲存整個檔案的數組。因為切片引用了原始的數組,導致GC不能釋放數組的空間;一個小的需求導致需要儲存整個檔案。
(切片引用了原始數組,切片操作不會影響到底層數組,返回以後導致GC不能釋放數組空間。所以修複這個問題需要將切片拷貝到一個新的切片中,舊數組在方法返回時就會釋放)
要修複整個問題,可以將感興趣的資料複製到一個新的切片中:
func CopyDigits(filename string) []byte { b, _ := ioutil.ReadFile(filename) b = digitRegexp.Find(b) c := make([]byte, len(b)) copy(c, b) return c}