mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-14 02:22:50 +00:00
make loop
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
Slice(切片)代表變長的序列,序列中每個元素都有相同的類型。一個slice類型一般寫作[]T,其中T代表slice中元素的類型;語法和數組很像,隻是沒有固定長度而已。
|
||||
|
||||
數組和slice之間有着緊密的聯繫。一個slice是一個輕量級的數據结构,提供了訪問數組子序列(或者全部)元素的功能,因爲slice的底層確實引用一個數組對象。一個slice由三個部分構成:指針、長度和容量。指針指向第一個slice元素對應的底層數組元素的地址,要注意的是slice的第一個元素併不一定就是數組的第一個元素。長度對應slice中元素的數目;長度不能超過容量,容量一般是從slice的開始位置到底層數據的結尾位置。內置的len和cap函數分别返迴slice的長度和容量。
|
||||
數組和slice之間有着緊密的聯繫。一個slice是一個輕量級的數據結構,提供了訪問數組子序列(或者全部)元素的功能,因爲slice的底層確實引用一個數組對象。一個slice由三個部分構成:指針、長度和容量。指針指向第一個slice元素對應的底層數組元素的地址,要註意的是slice的第一個元素併不一定就是數組的第一個元素。長度對應slice中元素的數目;長度不能超過容量,容量一般是從slice的開始位置到底層數據的結尾位置。內置的len和cap函數分别返迴slice的長度和容量。
|
||||
|
||||
多個slice之間可以共享底層的數據,併且引用的數組部分區間可能重疊。圖4.1顯示了表示一年中每個月份名字的字符串數組,還有重疊引用了該數組的兩個slice。數組這樣定義
|
||||
|
||||
@@ -35,7 +35,7 @@ for _, s := range summer {
|
||||
}
|
||||
```
|
||||
|
||||
如果切片操作超出cap(s)的上限將導致一個panic異常,但是超出len(s)則是意味着擴展了slice,因为新slice的長度會變大:
|
||||
如果切片操作超出cap(s)的上限將導致一個panic異常,但是超出len(s)則是意味着擴展了slice,因爲新slice的長度會變大:
|
||||
|
||||
```Go
|
||||
fmt.Println(summer[:20]) // panic: out of range
|
||||
@@ -46,7 +46,7 @@ fmt.Println(endlessSummer) // "[June July August September October]"
|
||||
|
||||
另外,字符串的切片操作和[]byte字節類型切片的切片操作是類似的。它們都寫作x[m:n],併且都是返迴一個原始字節繫列的子序列,底層都是共享之前的底層數組,因此切片操作對應常量時間複雜度。x[m:n]切片操作對於字符串則生成一個新字符串,如果x是[]byte的話則生成一個新的[]byte。
|
||||
|
||||
因爲slice值包含指向第一個slice元素的指針,因此向函數傳遞slice將允许在函數內部脩改底層數組的元素。換句話説,复制一個slice隻是對底層的數組創建了一個新的slice别名(§2.3.2)。下面的reverse函數在原內存空間將[]int類型的slice反轉,而且它可以用於任意長度的slice。
|
||||
因爲slice值包含指向第一個slice元素的指針,因此向函數傳遞slice將允許在函數內部脩改底層數組的元素。換句話説,複製一個slice隻是對底層的數組創建了一個新的slice别名(§2.3.2)。下面的reverse函數在原內存空間將[]int類型的slice反轉,而且它可以用於任意長度的slice。
|
||||
|
||||
```Go
|
||||
gopl.io/ch4/rev
|
||||
@@ -80,7 +80,7 @@ fmt.Println(s) // "[2 3 4 5 0 1]"
|
||||
|
||||
要註意的是slice類型的變量s和數組類型的變量a的初始化語法的差異。slice和數組的字面值語法很類似,它們都是用花括弧包含一繫列的初始化元素,但是對於slice併沒有指明序列的長度。這會隱式地創建一個合適大小的數組,然後slice的指針指向底層的數組。就像數組字面值一樣,slice的字面值也可以按順序指定初始化值序列,或者是通過索引和元素值指定,或者的兩種風格的混合語法初始化。
|
||||
|
||||
和數組不同的是,slice之间不能比較,因此我們不能使用==操作符來判斷兩個slice是否含有全部相等元素。不過標準庫提供了高度優化的bytes.Equal函數來判斷兩個字節型slice是否相等([]byte),但是對於其他類型的slice,我們必鬚自己展開每個元素進行比較:
|
||||
和數組不同的是,slice之間不能比較,因此我們不能使用==操作符來判斷兩個slice是否含有全部相等元素。不過標準庫提供了高度優化的bytes.Equal函數來判斷兩個字節型slice是否相等([]byte),但是對於其他類型的slice,我們必鬚自己展開每個元素進行比較:
|
||||
|
||||
```Go
|
||||
func equal(x, y []string) bool {
|
||||
@@ -115,7 +115,7 @@ s = []int(nil) // len(s) == 0, s == nil
|
||||
s = []int{} // len(s) == 0, s != nil
|
||||
```
|
||||
|
||||
如果你需要測試一個slice是否是空的,使用len(s) == 0來判斷,而不应该用s == nil來判斷。除了和nil相等比較外,一個nil值的slice的行爲和其它任意0産長度的slice一樣;例如reverse(nil)也是安全的。除了文檔已經明確説明的地方,所有的Go語言函數應該以相同的方式對待nil值的slice和0長度的slice。
|
||||
如果你需要測試一個slice是否是空的,使用len(s) == 0來判斷,而不應該用s == nil來判斷。除了和nil相等比較外,一個nil值的slice的行爲和其它任意0産長度的slice一樣;例如reverse(nil)也是安全的。除了文檔已經明確説明的地方,所有的Go語言函數應該以相同的方式對待nil值的slice和0長度的slice。
|
||||
|
||||
內置的make函數創建一個指定元素類型、長度和容量的slice。容量部分可以省略,在這種情況下,容量將等於長度。
|
||||
|
||||
|
Reference in New Issue
Block a user