golang基礎之陣列
1 陣列介紹
陣列是同一型別元素的集合。例如,整數集合 5,8,9,79,76 形成一個陣列。Go 語言中不允許混合不同型別的元素,例如包含字串和整數的陣列。(注:當然,如果是 interface{} 型別陣列,可以包含任意型別) 。
2 陣列常見操作
一個陣列的表示形式為 [n]T
。n
表示陣列中元素的數量,T
代表每個元素的型別。元素的數量 n
也是該型別的一部分 。
2.1 陣列初始化
一維陣列初始化如下
func main() { var a [4]int //元素自動初始化為零[0 0 0 0] b := [4]int{2, 5} //未提供初始化值得元素自動初始化為0 [2 5 0 0] c := [4]int{5, 3: 10} //可指定索引位置初始化 [5 0 0 10] d := [...]int{1, 2, 3} //編譯器按初始化值數量確定陣列長度 [1 2 3] e := [...]int{10, 3: 100} //支援索引初始化,但注意陣列長度與此有關 [10 0 0 100] fmt.Println(a, b, c, d, e)}
對於結構等複合型別,可省略元素初始化型別標籤
package mainimport "fmt"func main() { type user struct { name string age byte } d := [...]user{ {"tom", 20},// 可省略元素型別。 {"lee", 18},// 別忘了最後一行的逗號。 } fmt.Printf("%#vn", d)}/*output[2]main.user{main.user{name:"tom", age:0x14}, main.user{name:"lee", age:0x12}}*/
在定義多維陣列時,僅第一維度允許使用“...”
package mainimport "fmt"func main() { a := [2][2]int{ {1, 2}, {3, 4}, } b := [...][2]int{ {10, 20}, {30, 40}, } c := [...][2][2]int{ //三維陣列 { {1, 2}, {3, 4}, }, { {10, 20}, {30, 40}, }, } fmt.Println(a) //[[1 2] [3 4]] fmt.Println(b) //[[10 20] [30 40]] fmt.Println(c) //[[[1 2] [3 4]] [[10 20] [30 40]]]}
多維陣列定義
package mainimport ( "fmt")var arr0 [5][3]intvar arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}func main() { a := [2][3]int{{1, 2, 3}, {4, 5, 6}} b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 緯度不能用 "..."。 fmt.Println(arr0, arr1) fmt.Println(a, b)}/*output[[0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0]] [[1 2 3] [7 8 9]][[1 2 3] [4 5 6]] [[1 1] [2 2] [3 3]] */
2.2 陣列索引
陣列的索引從 0
開始到 length - 1
結束
func main() { var a [3]int //int array with length 3 a[0] = 12 // array index starts at 0 a[1] = 78 a[2] = 50 fmt.Println(a)}
2.3 陣列是值型別
Go 中的陣列是值型別而不是引用型別。這意味著當陣列賦值給一個新的變數時,該變數會得到一個原始陣列的一個副本。如果對新變數進行更改,則不會影響原始陣列。
func main() { a := [...]string{"USA", "China", "India", "Germany", "France"} b := a // a copy of a is assigned to b b[0] = "Singapore" fmt.Println("a is ", a) //a is [USA China India Germany France] fmt.Println("b is ", b) //b is [Singapore China India Germany France]}
上述程式中,a
的副本被賦給 b
。在第 4 行中,b
的第一個元素改為 Singapore
。這不會在原始陣列 a
中反映出來。
同樣,當陣列作為引數傳遞給函式時,它們是按值傳遞,而原始陣列保持不變。
package mainimport "fmt"func changeLocal(num [5]int) { num[0] = 55 fmt.Println("inside function ", num)}func main() { num := [...]int{5, 6, 7, 8, 8} fmt.Println("before passing to function ", num) changeLocal(num) //num is passed by value fmt.Println("after passing to function ", num)}/*outputbefore passing to function [5 6 7 8 8]inside function [55 6 7 8 8]after passing to function [5 6 7 8 8]*/
在上述程式的 13 行中, 陣列 num
實際上是透過值傳遞給函式 changeLocal
,陣列不會因為函式呼叫而改變。
值複製行為會造成效能問題,通常會建議使用 slice,或陣列指標。
package mainimport ( "fmt")func test(x [2]int) { fmt.Printf("x: %pn", &x) x[1] = 1000}func main() { a := [2]int{} fmt.Printf("a: %pn", &a) test(a) fmt.Println(a)}/*output:a: 0xc042062080x: 0xc0420620c0[0 0] */
2.4 陣列長度和元素數量
透過將陣列作為引數傳遞給 len
函式,可以得到陣列的長度。 cap
可以得到元素數量
package mainimport "fmt"func main() { a := [...]float64{67.7, 89.8, 21, 78} fmt.Println("length of a is", len(a)) //length of a is 4 fmt.Println("num of a is",cap(a)) //num of a is 4}
注意:內建函式len和cap都返回第一維度長度
package mainfunc main() { a := [2]int{} b := [...][2]int{ {10, 20}, {30, 40}, {50, 60}, } println(len(a), cap(a)) // 2 2 println(len(b), cap(b)) // 3 3 println(len(b[1]), cap(b[1])) // 2 2}
####2.5 使用 range 迭代陣列
for
迴圈可用於遍歷陣列中的元素。
package mainimport "fmt"func main() { a := [...]float64{67.7, 89.8, 21, 78} for i := 0; i < len(a); i++ { // looping from 0 to the length of the array fmt.Printf("%d th element of a is %.2fn", i, a[i]) }}
上面的程式使用 for
迴圈遍歷陣列中的元素,從索引 0
到 length of the array - 1
Go 提供了一種更好、更簡潔的方法,透過使用 for
迴圈的 range 方法來遍歷陣列。range
返回索引和該索引處的值。讓我們使用 range 重寫上面的程式碼。我們還可以獲取陣列中所有元素的總和。
package mainimport "fmt"func main() { a := [...]float64{67.7, 89.8, 21, 78} sum := float64(0) for i, v := range a { //range returns both the index and value fmt.Printf("%d the element of a is %.2fn", i, v) sum += v } fmt.Println("nsum of all elements of a", sum)}
上述程式的第 8 行 for i, v := range a
利用的是 for 迴圈 range 方式。 它將返回索引和該索引處的值。 我們列印這些值,並計算陣列 a
中所有元素的總和。
如果你只需要值並希望忽略索引,則可以透過用 _
空白識別符號替換索引來執行。
for _, v := range a { // ignores index }
上面的 for 迴圈忽略索引,同樣值也可以被忽略。
2.6 陣列運算子操作
如元素型別支援"==,!="運算子,那麼陣列也支援此操作
package mainfunc main() { var a, b [2]int println(a == b) //true c := [2]int{1, 2} d := [2]int{0, 1} println(c != d) //true /* var e, f [2]map[string]int println(e == f) //invalid operation: e == f ([2]map[string]int cannot be compared) */}
3 陣列高階用法
3.1 多維陣列
到目前為止我們建立的陣列都是一維的,Go 語言可以建立多維陣列。
package mainimport ( "fmt")func printArray(a [3][2]string) { for _, v1 := range a { for _, v2 := range v1 { fmt.Printf("%s ", v2) } fmt.Printf("n") }}func main() { a := [3][2]string{ {"lion", "tiger"}, {"cat", "dog"}, {"pigeon", "peacock"}, // this comma is necessary. The compiler will complain if you omit this comma } printArray(a) var b [3][2]string b[0][0] = "apple" b[0][1] = "samsung" b[1][0] = "microsoft" b[1][1] = "google" b[2][0] = "AT&T" b[2][1] = "T-Mobile" fmt.Printf("n") printArray(b)}/*outputlion tiger cat dog pigeon peacock apple samsung microsoft google AT&T T-Mobile */
多維陣列遍歷
package mainimport ( "fmt")func main() { var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}} for k1, v1 := range f { for k2, v2 := range v1 { fmt.Printf("(%d,%d)=%d ", k1, k2, v2) } fmt.Println() }}/*output:(0,0)=1 (0,1)=2 (0,2)=3 (1,0)=7 (1,1)=8 (1,2)=9 */
3.2 陣列指標和指標陣列
要分清指標陣列和陣列指標的區別。指標陣列是指元素為指標型別的陣列,陣列指標是獲取陣列變數的地址。
package mainimport "fmt"func main() { x, y := 10, 20 a := [...]*int{&x, &y} p := &a fmt.Printf("%T,%vn", a, a) //[2]*int,[0xc042062080 0xc042062088] fmt.Printf("%T,%vn", p, p) //*[2]*int,&[0xc042062080 0xc042062088]}
可獲取任意元素地址
func main() { a := [...]int{1, 2} println(&a, &a[0], &a[1]) //0xc042049f68 0xc042049f68 0xc042049f70}
陣列指標可以直接用來操作元素
func main() { a := [...]int{1, 2} p := &a p[1] += 10 println(p[1]) //12}
4 陣列使用常見坑
定義陣列型別時,陣列長度必須是非負整型常量表示式,長度是型別組成部分。也就是說,元素型別相同,但長度不同的陣列不屬於同一型別。
例子:
func main() { var d1 [3]int var d2 [2]int d1 = d2 //cannot use d2 (type [2]int) as type [3]int in assignment}
5 陣列總結
陣列:是同一種資料型別的固定長度的序列。
陣列定義:
var a [len]int
,比如:var a [5]int
,陣列長度必須是常量,且是型別的組成部分。一旦定義,長度不能變。長度是陣列型別的一部分,因此,
var a[5] int
和var a[10]int
是不同的型別。-
陣列可以透過下標進行訪問,下標是從
0
開始,最後一個元素下標是:len-1
。陣列索引常用操作如下:for i := 0; i < len(a); i++ { ...} for index, v := range a { ...}
訪問越界,如果下標在陣列合法範圍之外,則觸發訪問越界,會
panic
陣列是值型別,賦值和傳參會複製整個陣列,而不是指標。因此改變副本的值,不會改變本身的值。
支援 "=="、"!=" 運算子,因為記憶體總是被初始化過的。
指標陣列
[n]*T
,陣列指標*[n]T
。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/151/viewspace-2817637/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Golang 基礎-資料型別-陣列和切片Golang資料型別陣列
- 基礎資料結構之陣列資料結構陣列
- golang 之slice 變長陣列Golang陣列
- 陣列基礎使用陣列
- JavaScript基礎(五)陣列JavaScript陣列
- JavaScript基礎——使用陣列JavaScript陣列
- 樹狀陣列基礎陣列
- golang陣列分割Golang陣列
- Go 之基礎速學 (九) golang 裡的結構體繼承和陣列初步學習Golang結構體繼承陣列
- Golang 基礎之基礎語法梳理 (三)Golang
- JAVA基礎--二維陣列Java陣列
- NumPy 基礎 (一) - 建立陣列陣列
- 資料結構基礎學習之(串與陣列)資料結構陣列
- Golang 基礎之物件導向Golang物件
- golang 陣列去重 移除陣列指定元素Golang陣列
- C語言基礎-1、陣列C語言陣列
- Go 基礎教程--6 陣列 ArrayGo陣列
- Go 基礎教程--5 陣列 ArrayGo陣列
- NumPy 基礎 (二) - 陣列運算陣列
- 【重溫基礎】10.陣列陣列
- java基礎(十) 陣列型別Java陣列型別
- 6-Java基礎語法-陣列之一維陣列Java陣列
- Golang 基礎之函式使用 (三)Golang函式
- Golang 基礎之函式使用 (一)Golang函式
- Golang 基礎之函式使用 (二)Golang函式
- (二)golang陣列和切片Golang陣列
- golang 陣列面試題Golang陣列面試題
- Golang陣列注意細節Golang陣列
- golang實現稀疏陣列Golang陣列
- golang-陣列基本使用Golang陣列
- JavaSE基礎語法3-陣列Java陣列
- 零基礎學Java(8)陣列Java陣列
- JS-陣列基礎知識3JS陣列
- Java集合原始碼分析之基礎(一):陣列與連結串列Java原始碼陣列
- Golang 基礎之併發知識 (三)Golang
- ?Java基礎之Java列舉Java
- JavaScript基礎總結(三)——陣列總結JavaScript陣列
- JS基礎入門篇(十)— 陣列方法JS陣列