第4课 Go数组Array和切片Slice

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lhdalhd1996/article/details/52050772

数组array

package main

import (
    "fmt"
)

func main() {
    /*
        数组Array
        -定义数组的格式: var<varName>[n]<type> ,n>=0
        -数组长度也是类型的一部分,因此具有不同长度的数组为不同类型
        -注意区分指向数组的指针和指针数组
        -数组在Go中为值类型
        -数组之间可以使用==或者!=进行比较,但不可以使用<或者>
        -可以使用new来创建数组,此方法返回一个指向数组的指针
        -Go支持多维数组

        -Go语言版冒泡排序
    */
    var a [2]int
    var b [1]int
    //注意a和b是两种数据类型!
    //b = a此操作不可行
    fmt.Println(a)
    fmt.Println(b)
    //输出结果是
    //  [0 0]
    //  [0]
    fmt.Println("----")

    c := [2]int{1, 1} //初始化方法1
    d := [2]int{1}    //初始化方法2
    fmt.Println(c)
    fmt.Println(d)
    //会自动把d的第二个元素赋0值
    fmt.Println("----")

    e := [20]int{19: 3} //初始化方法3
    fmt.Println(e)
    fmt.Println("----")

    f := [...]int{0: 1, 1: 2, 2: 3} //初始化方法4
    fmt.Println(f)
    fmt.Println("----")

    g := [...]int{19: 1}
    fmt.Println(g) //初始化方法5
    fmt.Println("----")
}

指向数组的指针和指针数组,多维数组

package main

import (
    "fmt"
)

func main() {
    a := [...]int{99: 1}
    var p *[100]int = &a //创建了指向元素数为100的数组的指针p并且赋值以a的地址
    fmt.Println(p)
    //p为指向数组的指针

    x, y := 1, 2
    b := [...]*int{&x, &y} //创建了一个数组b,数组元素为指针
    fmt.Println(b)
    fmt.Println("-----")

    c := [2]int{1, 2}
    d := [2]int{1, 2}
    fmt.Println(c == d) //输出为true

    /*
        e := [2]int{1, 2}
        f := [1]int{1}
        fmt.Println(e==f) //输出为true
        不可以进行比较,会有编译错误
    */
    e := [10]int{}
    e[1] = 2
    fmt.Println(e)
    f := new([10]int)
    f[1] = 2
    fmt.Println(f)
    //不管是指向数组的指针,或者是数组指针都可以使用f[1]=2这种行形式来操作数组
    fmt.Println("-----")

    g := [...][3]int{ //顶级的数组可以用...来自动计算,非顶级的中括号内不可以用[...]
        {1, 1, 1},
        {2, 2, 2}}
    fmt.Println(g)
    //多维数组,同样也可以像操作一维数组一样对待多维数组
    fmt.Println("-----")
}

Go语言版冒泡排序如下:

package main

import (
    "fmt"
)

func main() {
    a := [...]int{5, 2, 6, 3, 9}
    fmt.Println(a)

    num := len(a)
    for i := 0; i < num; i++ {
        for j := i + 1; j < num; j++ {
            if a[i] < a[j] {
                temp := a[i]
                a[i] = a[j]
                a[j] = temp
            }
        }
    }
    fmt.Println(a)
}

切片
slice和reslice及底层数组的关系

package main

import (
    "fmt"
)

func main() {
    /*
        切片Slice
        -其本身不是数组,它指向底层的数组
        -作为变长数组的替代方案,可以关联底层数组的局部或全部
        -为引用类型
        -可以直接创建或从底层数组获取生成
        -使用len()获取元素个数,cap()获取容量
        一般使用make()创建
        -如果多个slice指向相同底层数组,其中一个的值改变会影响全部


        -make([]T,len,cap)
        -其中cap可以省略,则和len的值相同
        -len表示存数的元素个数,cap表示容量
    */

    var s1 []int    //这就完成了创建切片
    fmt.Println(s1) //输出[] 一个元素也没有

    a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(a)  //打印出1到9和一个0
    s1 = a[5:10]    //s2为切片,a[5,6,7,8,9] 可见包括索引为5但是不包括10
    fmt.Println(s1) //输出[6 7 8 9 0]

    s2 := a[5:len(a)] //从索引为5取到尾部
    fmt.Println(s2)

    s3 := a[:5] //取前五个元素
    fmt.Println(s3)

    s4 := a[5:] //从索引为5取到尾部
    fmt.Println(s4)
    fmt.Println("-----")

    s5 := make([]int, 3, 10) //另外一种声明方法,保存int,目前包含多少个元素,容量
    //当切片中元素超过容量时,容量增加一倍,由10变成20,再变成40
    fmt.Println(len(s5), cap(s5))
    //也可以省略那个10,这时候会默认认为容量=元素数=3
    fmt.Println("-----")

    /*
        Reslice
        -Reslice时索引以被slice的切片为准
        =索引不可以超过被slice的切片的容量cap()值
        -索引越界不会导致底层数组的重新分配而是引发错误

        Append
        -可以在slice尾部追加元素
        -可以将一个slice追加在另一个slice尾部
        -如果最终长度未超过追加到slice的容量则返回原始slice
        -如果超过追加到的slice的容量则将重新分配并拷贝原始数据

        Copy
    */
    s6 := make([]int, 3, 6)
    fmt.Printf("%p\n", s6)
    s6 = append(s6, 1, 2, 3) //将1,2,3添加到s6尾部,并且返回一个新的指针赋给了s6
    fmt.Printf("%v %p\n", s6, s6)
    //未超过切片容量,地址不变化
    s6 = append(s6, 1, 2, 3)
    fmt.Printf("%v %p\n", s6, s6)
    //超过切片容量,重新分配,地址变化
    fmt.Println("-----")

    s7 := []int{1, 2, 3, 4, 5, 6}
    s8 := []int{7, 8, 9}
    copy(s7, s8)
    fmt.Println(s7)
    //s7变成了7,8,9,4,5,6
    //s8还是 7,8,9
    //把短的拷贝给多的,只影响相应的位数
    //但是如果反过来呢?
    s9 := []int{1, 2, 3, 4, 5, 6}
    s10 := []int{7, 8, 9}
    copy(s10, s9)
    fmt.Println(s10)
    //s10变成了123
    //s9还是1,2,3,4,5,6
    //把多的拷贝给短的,也只影响相应的位数
    copy(s10, s9[2:5]) //如果想拷贝一部分(拷贝s9[2,3,4])
    fmt.Println(s10)
}

运行结果如下:
[]
[1 2 3 4 5 6 7 8 9 0]
[6 7 8 9 0]
[6 7 8 9 0]
[1 2 3 4 5]
[6 7 8 9 0]
—–
3 10
—–
0xc04203fd70
[0 0 0 1 2 3] 0xc04203fd70
[0 0 0 1 2 3 1 2 3] 0xc04203a1e0
—–
[7 8 9 4 5 6]
[1 2 3]
[3 4 5]

猜你喜欢

转载自blog.csdn.net/lhdalhd1996/article/details/52050772