數組
數組(Array)是類型相同元素的集合。不允許在一個數組使用不同類型的元素(比如:不允許整數和字元串一起使用)。
- 數組長度是不可變的
- 數組是值類型
- 數組之間可以用== 或 !=比較(但是長度也是類型的一部分,長度不同,是兩個不同類型,不能使用==和!=)
- 聲明方式
//聲明一個長度為3的整數類型。數組的所有元素都自動指派為元素類型的0值
var a [3]int
fmt.Println(a) // [0 0 0]
var b [3]bool
fmt.Println(b) // [false false false]
//數組的索引是從0開始,是以a[1]是給第二個元素指派
a[1] = 100
a[2] = 200
fmt.Println(a) // [0 100 200]
//速記聲明,在數組類型後面加一對大括号{},在大括号裡面寫元素初始值清單,多個值用逗号分隔
c := [5]int{1, 2, 3, 4, 5}
fmt.Println(c) // [1 2 3 4 5]
//通過下标指派,預設指派第一個元素,剩下的自動指派0
d := [3]int{12}
fmt.Println(d) // [12 0 0]
// 指派第三個元素
e := [3]int{2:12}
fmt.Println(e) // [0 0 12]
//使用省略号,讓編譯器自動推到長度
f := [...]int{12, 78, 50}
fmt.Println(f) // [12 78 50]
- 數組是值類型,如果數組的變量被指派時,将會或者原來數組的copy,新數組中元素的改變不會影響原數組中元素的值
// 數組bb改變後沒有影響aa
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
bb := aa
bb[0] = "THAT"
fmt.Println("aa is ", aa) // aa is [THIS IS TEST ARRAY]
fmt.Println("bb is ", bb) // bb is [THAT IS TEST ARRAY]
//切片dd改變後影響了cc
cc := []string{"THIS", "IS", "TEST", "ARRAY"}
dd := cc
dd[0] = "THAT"
fmt.Println("cc is ", cc) // cc is [THAT IS TEST ARRAY]
fmt.Println("dd is ", dd) // dd is [THAT IS TEST ARRAY]
- 通過len()擷取數組長度
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
fmt.Println("aa length is ", len(aa)) // aa length is 4
- 資料周遊
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
//使用 range周遊
for i, v := range aa {
fmt.Printf("index= %d, value=%s\n", i, v)
}
// 使用len進行周遊
for i:=0; i< len(aa); i++ {
fmt.Printf("index= %d, value=%s\n", i, aa[i])
}
// index= 0, value=THIS
// index= 1, value=IS
// index= 2, value=TEST
// index= 3, value=ARRAY
//如果隻想擷取數組的值,不需要數組的索引可以使用辨別符"_"
for _, v := range aa {
fmt.Printf("value=%s\n", v)
}
//指針數組(首先是個數組,數組的元素都是指針)
var pa [4]*string
for i,v := range aa {
fmt.Printf("index= %d, value=%s\n", i, v)
pa[i] = &aa[i]
}
// index= 0, value=THIS
// index= 1, value=IS
// index= 2, value=TEST
// index= 3, value=ARRAY
// [0xc00005e100 0xc00005e110 0xc00005e120 0xc00005e130]
//數組指針(首先是個指針,它隻想一個數組)
var pa2 *[4]string
pa2 = &aa
fmt.Println(*pa2)
fmt.Println(pa2)
// [THIS IS TEST ARRAY]
// &[THIS IS TEST ARRAY]
- 多元數組
aaa := [3][2]string{
{"1", "2"},
{"11", "22"},
{"111", "222"},
}
for _,v1 := range aaa {
fmt.Printf("v1=%s\n", v1)
for _,v2 := range v1 {
fmt.Printf("v2=%s\n", v2)
}
}
// v1=[1 2]
// v2=1
// v2=2
// v1=[11 22]
// v2=11
// v2=22
// v1=[111 222]
// v2=111
// v2=222
切片slice
切片不是數組,不存儲任何元素,它是對數組的引用。切片比數組更為友善、靈活。
切片類型的字面量表示:
[] T :T是元素類型,比如:
[] int
[]string
- 切片的建立
//使用make建立切片
s := make([]string, 3)
fmt.Println("emp", s) // emp [ ]
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("set", s) // set [a b c]
fmt.Println("set", s[2]) // set c
fmt.Println("set", len(s)) // set 3
var s2 = []int{1,2,3,4}
s3 := []int{1,2,3,4}
fmt.Println(s2) // [1 2 3 4]
fmt.Println(s3) // [1 2 3 4]
- append添加元素
// 使用append追加元素
s = append(s, "d")
//使用len()擷取長度,cap()擷取容量
fmt.Println("length : ",len(s)) // length : 4
//如果添加過程中容量不夠,則自動擴容,容量是在原來的基礎上乘以2
fmt.Println("cap : ",cap(s)) // cap : 6
s = append(s, "e", "f")
fmt.Println(s) //[a b c d e f]
s = append(s, "g")
fmt.Println("cap : ",cap(s)) // cap : 12
- 修改切片
//修改切片會改變原來資料
darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}
//含第三個元素,不含第6個元素
dslice := darr[2:5]
fmt.Println("array before",darr) // array before [57 89 90 82 100 78 67 69 59]
for i := range dslice {
dslice[i]++
}
fmt.Println("array after",darr) // array after [57 89 91 83 101 78 67 69 59]
//含第三個元素,不含第6個元素
sl := darr[2:5]
fmt.Println(sl) // [90 82 100]
// 從開始到第5個元素(不含第6個)
sEnd := darr[:5]
fmt.Println(sEnd) // [57 89 90 82 100]
// 從第3個到最後
sBegin := darr[2:]
fmt.Println(sBegin) // [90 82 100 78 67 69 59]
// 共享同一個底層數組時,對每一個切片的修改都會反映在底層數組中
dsilece1 := darr[:] // 從0到最後
dsilece2 := darr[:]
fmt.Println("array before change",darr) // array before change [57 89 90 82 100 78 67 69 59]
dsilece1[0] = 1
fmt.Println("array change 1",darr) // array change 1 [1 89 90 82 100 78 67 69 59]
dsilece2[1] = 2
fmt.Println("array change 2",darr) // array change 2 [1 2 90 82 100 78 67 69 59]
- 周遊和多元切片
var s2 = []int{1,2,3,4}
for _,v := range s2 {
fmt.Println(v) // 1 2 3 4
}
slice3 := [][]string {
{"C", "C++"},
{"JavaScript"},
{"Go", "Rust"},
}
for _, v1 := range slice3 {
fmt.Printf("%s ", v1)
for _, v2 := range v1 {
fmt.Printf("%s ", v2)
fmt.Printf("\n")
}
}
// v1=[C C++]
// v2=C
// v2=C++
// v1=[JavaScript]
// v2=JavaScript
// v1=[Go Rust]
// v2=Go
// v2=Rust
平常使用切片比數組要多。