数组

数组(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]

- 
``` bash
// 数组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]

aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
fmt.Println("aa length is ", len(aa)) // aa length is  4
- 数据遍历
``` bash
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  
切片不是数组,不存储任何元素,它是对数组的引用。切片比数组更为方便、灵活。<br> 切片类型的字面量表示:  
> 
[] T :T是元素类型,比如: [] int []string

- 
``` bash
//使用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追加元素 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

- 
``` bash
//修改切片会改变原来数据
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


平常使用切片比数组要多。