09丨数组和切片

09丨数组和切片

数组的声明

var a [3]int //声明并初始化为默认零值
a[0] = 1
b := [3]int{1, 2, 3} //声明同时初始化
c := [2][2]int{{1, 2}, {3, 4}} //多维数组初始化

数组元素遍历

与其他主要编程语⾔的差异
func TestTravelArray(t *testing.T) {
 a := [...]int{1, 2, 3, 4, 5} //不指定元素个数
 for idx/*索引*/, elem/*元素*/ := range a {
 fmt.Println(idx, elem)
 }
}

数组截取

a[开始索引(包含), 结束索引(不包含)]
a :
= [...]int{1, 2, 3, 4, 5} a[1:2] //2 a[1:3] //2,3 a[1:len(a)] //2,3,4,5 a[1:] //2,3,4,5 a[:3] //1,2,3

练习样例

package ch6

import "testing"

// 定义数组
func TestArrayInt(t *testing.T) {
    var arr [3]int
    t.Log(arr[1], arr[2]) //array_test.go:7: 0 0
    arr1 := [4]int{1, 2, 3, 4}
    arr2 := [...]int{1, 3, 4, 5} // 不写数组的长度
    arr1[1] = 5
    t.Log(arr1[1], arr1, arr2) //array_test.go:11: 5 [1 5 3 4] [1 3 4 5]
}

// 数组的遍历
func TestArrayTravel(t *testing.T) {
    arr3 := [...]int{1, 3, 4, 5}

    // 不建议采用这种写法去遍历数组
    for i := 0; i < len(arr3); i++ {
        t.Log(arr3[i])
    }
    //推荐的写法
    for idx, e := range arr3 {
        t.Log(idx, e)
    }
    for _, e := range arr3 {
        t.Log(e)
    }
}

// 数组截取
func TestArraySection(t *testing.T) {
    arr3 := [...]int{1, 3, 4, 5}
    arr3Sec := arr3[3:] //array_test.go:48: [5]
    //arr4_sec := arr3[-1:]  //不支持负数索引
    t.Log(arr3Sec)
}

切片内部结构

 

切片声明

var s0 []int
s0 = append(s0, 1)
s := []int{}
s1 := []int{1, 2, 3}
s2 := make([]int, 2, 4) 
 /*[]type, len, cap
 其中len个元素会被初始化为默认零值,未初始化元素不可以访问
 */

 

package ch6

import "testing"

func TestSliceInt(t *testing.T) {
    var s0 []int
    t.Log(len(s0), cap(s0)) //0 0

    s0 = append(s0, 1) //  slice_test.go:9: 1 1
    t.Log(len(s0), cap(s0))

    s1 := []int{1, 2, 3, 4}
    t.Log(len(s1), cap(s1),s1[0])  //4 4 1

    s2 := make([]int, 3, 5)
    t.Log(len(s2), cap(s2))  // 3 5
    //t.Log(s2[0], s2[1], s2[2],s2[3], s2[4]) // 异常
    t.Log(s2[0], s2[1], s2[2]) //     slice_test.go:18: 0 0 0
    s2 = append(s2, 1)
    t.Log(s2[0], s2[1], s2[2], s2[3])  // 0 0 0 1
    t.Log(len(s2), cap(s2)) //4 5
}

 

 

切片的容量增长

func TestSliceGrowing(t *testing.T) {
    s := []int{}
    for i := 0; i < 10; i++ {
        s = append(s, i)
        t.Log(len(s), cap(s))
    }
}

 

当容量不足时,成倍的增长

/*
=== RUN   TestSliceGrowing
slice_test.go:40: 1 1
slice_test.go:40: 2 2
slice_test.go:40: 3 4
slice_test.go:40: 4 4
slice_test.go:40: 5 8
slice_test.go:40: 6 8
slice_test.go:40: 7 8
slice_test.go:40: 8 8
slice_test.go:40: 9 16
slice_test.go:40: 10 16            //最初没有开始定义cap,因此cap是自增的,以满足slice的append操作
--- PASS: TestSliceGrowing (0.00s)
PASS*/
//最初没有开始定义cap,因此cap是自增的,以满足slice的append操作

 

切片共享存储结构

 

func TestSliceShareMemory(t *testing.T) {
    year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
        "Oct", "Nov", "Dec"}
    Q2 := year[3:6]
    t.Log(Q2, len(Q2), cap(Q2)) // [Apr May Jun] 3 9  // 指向的是后面连续的存储空间
    summer := year[5:8]
    t.Log(summer, len(summer), cap(summer)) //[Jun Jul Aug] 3 7 // 去掉前面的5个,还剩7个连续的存储空间
    summer[0] = "Unkown"                    //修改切片的值会影响整个切片
    t.Log(summer)                           // [Unkown Jul Aug]
    t.Log(Q2)                               //[Apr May Unkown]
    t.Log(year)                             //[Jan Feb Mar Apr May Unkown Jul Aug Sep Oct Nov Dec]

}

 

 

切片不能进行比较

func TestSliceComparing(t *testing.T) {
    a := []int{1, 2, 3, 4}
    b := []int{1, 2, 3, 4}
    if a == b { //invalid operation: a == b (slice can only be compared to nil)
        t.Log("equal")
    }
}

 

数组vs.切片


1.容量是否可伸缩

2.是否可以进行比较

切片不可以进行比较

 

posted @ 2021-01-21 20:11  元贞  阅读(70)  评论(0)    收藏  举报