go int 转切片_「快学 Go 语言」第 4 课——低调的数组
數組就是一篇連續的內存,幾乎所有的計算機語言都有數組,只不過 Go 語言里面的數組其實并不常用,這是因為數組是定長的靜態的,一旦定義好長度就無法更改,而且不同長度的數組屬于不同的類型,之間不能相互轉換相互賦值,用起來多有不方便之處。
切片是動態的數組,是可以擴充內容增加長度的數組。當長度不變時,它用起來就和普通數組一樣。當長度不同時,它們也屬于相同的類型,之間可以相互賦值。切片的便捷性讓數組的絕大多數應用領域都廣泛地被取代了。
不過也不可以小瞧數組,在切片的底層實現中,數組是切片的基石,是切片的特殊語法隱藏了內部的細節,讓用戶不能直接看到內部隱藏的數組。切片不過是數組的一個包裝,給頑固的數組裝上了靈活的翅膀,讓石頭也可以展翅飛翔。
僅僅是上面純文字的說明,讀者肯定會感覺很懵。下面讓我們來看具體的實例。
數組變量的定義
我們先試一下只申明類型,不賦初值。這時編譯器會給數組默認賦上「零值」。數組的零值就是所有內部元素的零值。
package mainimport "fmt"func main() {var a [9]intfmt.Println(a)}------------[0 0 0 0 0 0 0 0 0]復制代碼下面我們看看另外三種變量定義的形式, 效果都是一樣的
package mainimport "fmt"func main() {var a = [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}var b [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}c := [8]int{1, 2, 3, 4, 5, 6, 7, 8}fmt.Println(a)fmt.Println(b)fmt.Println(c)}---------------------[1 2 3 4 5 6 7 8 9][1 2 3 4 5 6 7 8 9 10][1 2 3 4 5 6 7 8]復制代碼數組的訪問
接下來我們使用下標來簡單操作一下數組,這個數組里存的是數字的平方值
package mainimport "fmt"func main() {var squares [9]intfor i := 0; i < len(squares); i++ {squares[i] = (i + 1) * (i + 1)}fmt.Println(squares)}--------------------[1 4 9 16 25 36 49 64 81]復制代碼數組的下標越界檢查(高階知識)
上面的代碼中我們注意到可以使用內置函數 len() 來直接獲取數組的長度。數組的長度是編譯期確定的,當我們使用 len() 函數訪問數組的長度屬性時,編譯器在背后偷偷把它替換成了整數值。
package mainimport "fmt"func main() {var a = [5]int{1,2,3,4,5}a[101] = 255fmt.Println(a)}-----./main.go:7:3: invalid array index 101 (out of bounds for 5-element array)復制代碼上面的代碼運行結果說明了 Go 語言會對數組訪問下標越界進行編譯器檢查。有一個重要的問題是,如果下標是一個變量,Go 是如何檢查下標越界呢?變量需要在運行時才可以決定是否越界,Go 是如何辦到的呢?
package mainimport "fmt"func main() {var a = [5]int{1,2,3,4,5}var b = 101a[b] = 255fmt.Println(a)}------------panic: runtime error: index out of rangegoroutine 1 [running]:main.main()/Users/qianwp/go/src/github.com/pyloque/practice/main.go:8 +0x3dexit status 2復制代碼答案是 Go 會在編譯后的代碼中插入下標越界檢查的邏輯,所以數組的下標訪問效率是要打折扣的,比不得 C 語言的數組訪問性能。
數組賦值
同樣的子元素類型并且是同樣長度的數組才可以相互賦值,否則就是不同的數組類型,不能賦值。數組的賦值本質上是一種淺拷貝操作,賦值的兩個數組變量的值不會共享。
package mainimport "fmt"func main() {var a = [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}var b [9]intb = aa[0] = 12345fmt.Println(a)fmt.Println(b)}--------------------------[12345 2 3 4 5 6 7 8 9][1 2 3 4 5 6 7 8 9]復制代碼從上面代碼的運行結果中可以看出賦值后兩個數組并沒有共享內部元素。如果數組的長度很大,那么拷貝操作是有一定的開銷的,使用的時候一定需要注意。下面我們嘗試使用不同長度的數組賦值會有什么結果
package mainimport "fmt"func main() {var a = [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}var b [10]intb = afmt.Println(b)}--------------------------./main.go:8:4: cannot use a (type [9]int) as type [10]int in assignment復制代碼可以看出不同長度的數組之間賦值是禁止的,因為它們屬于不同的類型。
數組的遍歷
數組除了可以使用下標進行遍歷之外,還可以使用 range 關鍵字來遍歷,range 遍歷提供了下面兩種形式。
package mainimport "fmt"func main() {var a = [5]int{1,2,3,4,5}for index := range a { fmt.Println(index, a[index]) } for index, value := range a {fmt.Println(index, value)}}------------0 11 22 33 44 50 11 22 33 44 5復制代碼考慮到切片的內容太多,我們將獨立一節專門講解切片,下一節將是 Go 語言的極有價值的一節,讀者一定要努力搞清楚每一個細節。
總結
以上是生活随笔為你收集整理的go int 转切片_「快学 Go 语言」第 4 课——低调的数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 传说之下地图素材_【开阔眼界】地图上的史
- 下一篇: js实现oss批量下载文件_js下载文件