原文連結:Go 語言的 4 個特性改動
前言
在 Go1.1 可以看到某個版本的 Go 語言一些改動文件(修改 URL 引數檢視別的版本)。
其中以 Go1.1#language 標籤下關於語言特性方面的尤為重要。
在每個 Go 語言新版本釋出後瀏覽一下,是個良好的習慣。
下面我會從 Go1.1 到 Go1.11 以來挑 4 個值得討論的改動來跟大家分享一下。
三索引切片
版本: Go1.2
在現有陣列或切片下,使用第二個冒號來指示新生成的切片的容量。
func TestThreeIndex(t *testing.T) {
s := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := s[2:4] // 等價於 s[2:4:cap(s)],省略取 cap(s)。
t.Log(s1) // [2, 3]
t.Log(len(s1), cap(s1)) // len = 2, cap = 8
// 可以訪問在 cap 以內的元素並且如果訪問在 len 和 cap 之間的元素就可以訪問到底層陣列。
t.Log(s1[0:7]) // [2, 3, 4, 5, 6, 7, 8, 9]
// 通過限制 cap 從而限制新的切片訪問底層陣列的能力。
// cap 取值必須小於或等於底層陣列 cap。
s2 := s[2:4:7] // cap = 7 - 2 = 5
t.Log(s2) // [2, 3]
t.Log(len(s2), cap(s2)) // len = 2, cap = 5
t.Log(s2[0:5]) // [2, 3, 4, 5, 6]
// error: slice bounds out of range
// 越界
t.Log(s2[0:7])
}
複製程式碼
for range 簡便寫法
版本:Go1.4
for range 不需要索引和索引對應的元素值的簡便寫法。
- 不需要索引。
for _, v := range s {
t.Log(v)
}
複製程式碼
- 不需要索引對應的值。
for i := range s {
t.Log(i)
}
複製程式碼
- (Go1.4新增)不需要索引和索引對應的值,單純地把容器型別元素的個數作為迭代的次數。
for range s {
...
}
複製程式碼
結構體型別轉換忽略標籤
版本:Go1.8
結構體型別轉換時,標籤會被忽略。也就是說,標籤不同的結構體之間也可以互相轉換型別。
注意:正常情況下(沒有標籤)的結構體型別之間的轉換隻有欄位名、型別和宣告的順序全部相同才合法。
type T1 struct {
X int `json:"foo"`
}
type T2 struct {
X int `json:"bar"`
}
var v1 T1
var v2 T2
v1 = T1(v2) // 現在是合法的
複製程式碼
型別別名
版本:Go1.9
型別別名:T1 完全是 T2 這個型別,這個新設計是為了重構和相容舊程式碼。
type T1 = T2
複製程式碼
型別宣告:T1 的底層資料型別是 T1。
type T1 T2
複製程式碼
一個簡單的區別就是:型別宣告和底層型別賦值時需要轉換,而型別別名不需要。