Golang基础之数组
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
1 數(shù)組介紹
數(shù)組是同一類型元素的集合。例如,整數(shù)集合 5,8,9,79,76 形成一個數(shù)組。Go 語言中不允許混合不同類型的元素,例如包含字符串和整數(shù)的數(shù)組。(注:當(dāng)然,如果是 interface{} 類型數(shù)組,可以包含任意類型) 。
2 數(shù)組常見操作
一個數(shù)組的表示形式為 [n]T。n 表示數(shù)組中元素的數(shù)量,T 代表每個元素的類型。元素的數(shù)量 n 也是該類型的一部分 。
2.1 數(shù)組初始化
一維數(shù)組初始化如下
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} //編譯器按初始化值數(shù)量確定數(shù)組長度 [1 2 3]
? ? e := [...]int{10, 3: 100} //支持索引初始化,但注意數(shù)組長度與此有關(guān) [10 0 0 100]
? ? fmt.Println(a, b, c, d, e)
}
對于結(jié)構(gòu)等復(fù)合類型,可省略元素初始化類型標(biāo)簽
package main
import "fmt"
func main() {
? ? type user struct {
? ? ? ? name string
? ? ? ? age ?byte
? ? }
? ? d := [...]user{
? ? ? ? {"tom", 20},// 可省略元素類型。
? ? ? ? {"lee", 18},// 別忘了最后一行的逗號。
? ? }
? ? fmt.Printf("%#v\n", d)
}
/*output
[2]main.user{main.user{name:"tom", age:0x14}, main.user{name:"lee", age:0x12}}
*/
在定義多維數(shù)組時,僅第一維度允許使用“…”
package main
import "fmt"
func main() {
? ? a := [2][2]int{
? ? ? ? {1, 2},
? ? ? ? {3, 4},
? ? }
? ? b := [...][2]int{
? ? ? ? {10, 20},
? ? ? ? {30, 40},
? ? }
? ? c := [...][2][2]int{ ? //三維數(shù)組
? ? ? ? {
? ? ? ? ? ? {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]]]
}
多維數(shù)組定義
package main
import (
? ? "fmt"
)
var arr0 [5][3]int
var 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 數(shù)組索引
數(shù)組的索引從 0 開始到 length - 1 結(jié)束
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 數(shù)組是值類型
Go 中的數(shù)組是值類型而不是引用類型。這意味著當(dāng)數(shù)組賦值給一個新的變量時,該變量會得到一個原始數(shù)組的一個副本。如果對新變量進(jìn)行更改,則不會影響原始數(shù)組。
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。這不會在原始數(shù)組 a 中反映出來。
同樣,當(dāng)數(shù)組作為參數(shù)傳遞給函數(shù)時,它們是按值傳遞,而原始數(shù)組保持不變。
package main
import "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)
}
/*output
before 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 行中, 數(shù)組 num 實(shí)際上是通過值傳遞給函數(shù) changeLocal,數(shù)組不會因?yàn)楹瘮?shù)調(diào)用而改變。
值拷貝行為會造成性能問題,通常會建議使用 slice,或數(shù)組指針。
package main
import (
? ? "fmt"
)
func test(x [2]int) {
? ? fmt.Printf("x: %p\n", &x)
? ? x[1] = 1000
}
func main() {
? ? a := [2]int{}
? ? fmt.Printf("a: %p\n", &a)
? ? test(a)
? ? fmt.Println(a)
}
/*
output:
a: 0xc042062080
x: 0xc0420620c0
[0 0]
?*/
2.4 數(shù)組長度和元素?cái)?shù)量
通過將數(shù)組作為參數(shù)傳遞給 len 函數(shù),可以得到數(shù)組的長度。 cap可以得到元素?cái)?shù)量
package main
import "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
}
注意:內(nèi)置函數(shù)len和cap都返回第一維度長度
package main
func 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 迭代數(shù)組
for 循環(huán)可用于遍歷數(shù)組中的元素。
package main
import "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 %.2f\n", i, a[i])
? ? }
}
上面的程序使用 for 循環(huán)遍歷數(shù)組中的元素,從索引 0 到 length of the array - 1
Go 提供了一種更好、更簡潔的方法,通過使用 for 循環(huán)的 range 方法來遍歷數(shù)組。range返回索引和該索引處的值。讓我們使用 range 重寫上面的代碼。我們還可以獲取數(shù)組中所有元素的總和。
package main
import "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 %.2f\n", i, v)
? ? ? ? sum += v
? ? }
? ? fmt.Println("\nsum of all elements of a", sum)
}
上述程序的第 8 行 for i, v := range a 利用的是 for 循環(huán) range 方式。 它將返回索引和該索引處的值。 我們打印這些值,并計(jì)算數(shù)組 a 中所有元素的總和。
如果你只需要值并希望忽略索引,則可以通過用 _ 空白標(biāo)識符替換索引來執(zhí)行。
for _, v := range a { // ignores index ?}
1
上面的 for 循環(huán)忽略索引,同樣值也可以被忽略。
2.6 數(shù)組操作符操作
如元素類型支持”==,!=”操作符,那么數(shù)組也支持此操作
package main
func 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 數(shù)組高級用法
3.1 多維數(shù)組
到目前為止我們創(chuàng)建的數(shù)組都是一維的,Go 語言可以創(chuàng)建多維數(shù)組。
package main
import (
? ? "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)
}
/*output
lion tiger?
cat dog?
pigeon peacock?
apple samsung?
microsoft google?
AT&T T-Mobile?
*/
多維數(shù)組遍歷
package main
import (
? ? "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 數(shù)組指針和指針數(shù)組
要分清指針數(shù)組和數(shù)組指針的區(qū)別。指針數(shù)組是指元素為指針類型的數(shù)組,數(shù)組指針是獲取數(shù)組變量的地址。
package main
import "fmt"
func main() {
? ? x, y := 10, 20
? ? a := [...]*int{&x, &y}
? ? p := &a
? ? fmt.Printf("%T,%v\n", a, a) ?//[2]*int,[0xc042062080 0xc042062088]
? ? fmt.Printf("%T,%v\n", p, p) ?//*[2]*int,&[0xc042062080 0xc042062088]
}
可獲取任意元素地址
func main() {
? ? a := [...]int{1, 2}
? ? println(&a, &a[0], &a[1]) ?//0xc042049f68 0xc042049f68 0xc042049f70
}
數(shù)組指針可以直接用來操作元素
func main() {
? ? a := [...]int{1, 2}
? ? p := &a
? ? p[1] += 10
? ? println(p[1]) ? //12
}
4 數(shù)組使用常見坑
定義數(shù)組類型時,數(shù)組長度必須是非負(fù)整型常量表達(dá)式,長度是類型組成部分。也就是說,元素類型相同,但長度不同的數(shù)組不屬于同一類型。
例子:
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 數(shù)組總結(jié)
數(shù)組:是同一種數(shù)據(jù)類型的固定長度的序列。
數(shù)組定義:var a [len]int,比如:var a [5]int,數(shù)組長度必須是常量,且是類型的組成部分。一旦定義,長度不能變。
長度是數(shù)組類型的一部分,因此,var a[5] int和var a[10]int是不同的類型。
數(shù)組可以通過下標(biāo)進(jìn)行訪問,下標(biāo)是從0開始,最后一個元素下標(biāo)是:len-1。數(shù)組索引常用操作如下:
for i := 0; i < len(a); i++ {
? ?...
}?
for index, v := range a {
? ?...
}?
訪問越界,如果下標(biāo)在數(shù)組合法范圍之外,則觸發(fā)訪問越界,會panic
數(shù)組是值類型,賦值和傳參會復(fù)制整個數(shù)組,而不是指針。因此改變副本的值,不會改變本身的值。
支持 “==”、”!=” 操作符,因?yàn)閮?nèi)存總是被初始化過的。
指針數(shù)組 [n]*T,數(shù)組指針*[n]T。
?
轉(zhuǎn)載于:https://my.oschina.net/u/3371661/blog/2994835
總結(jié)
以上是生活随笔為你收集整理的Golang基础之数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高并发架构系列:MQ消息队列的12点核心
- 下一篇: Linux基础命令---文本显示more