数组、切片、map

数组、切片、map

1. 数组

数组是同一个类型元素的集合,在内存中连续存放

定义时需要指明大小和类型

package main

import "fmt"

func main()  {
    // 1 定义了一个大小为3的int类型数组 没有初始化
    var a [3]int
    // 2 定义并赋初值 三种方式
    var a [3]int=[3]int{1, 3, 8}
    var a=[3]int{1, 3, 8}
    a:=[3]int{1, 3, 8}

    // 3 使用数组(从0开始)给数组赋值
    a[2] = 100

    // 4 只给第二个位置改为99
    a := [3]int{2:99}
    a := [3]int{2:99,1:88}

    // 5 数组的大小是类型的一部分
    //这两个不是一个类型
    var a [2]int
    var b [3]int

    // 6 数组是值类型,当参数传到函数中时,修改不会改变原来的值
    // go语言都是copy传递
    // python中都是引用传递,一切皆对象,就是地址,当做参数传递是把地址传过去了
    // python中比较特殊有可变类型与不可类型
    var a [3]int=[3]int{5, 6, 7}
    fmt.Println(a)
    test1(a)  // 在test1中修改a了不会修改原来的
    fmt.Println(a)

    // 7 数组的长度 内置len方法
    var a [3]int=[3]int{5,6,7}
    fmt.Println(len(a))  // 3

    // 8 循环数组
    //方式一
    var a [3]int=[3]int{5,6,7}
    for i:=0;i<len(a);i++{
        fmt.Println(a[i])
    }
    //方式二
    //range:是一个关键字
    //函数如果返回两个值,必须用两个值来接收
    //range可以用一个值来接收,如果用一个值来接收,就是索引
    var a [3]int=[3]int{5,6,7}
    for i,v:=range a{
        fmt.Println(i)  //索引
        fmt.Println(v)  //数组的值
    }
    //只取值,不取索引
    for _,v:=range a{
        fmt.Println(v)  //
    }

    // 9 多维数组
    //定义二维数组
    var a [3][2]int
    // 定义并赋值
    var a [3][2]int = [3][2]int{{1, 2}, {2, 3}, {19, 3}}
    a[1][1] = 999
    fmt.Println(a)

}

func test1(a [3]int)  {
    a[2] = 999
    fmt.Println(a)
}

2. 切片

切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。切片底层依附于数组

package main

import "fmt"

func main()  {
    // 1 基于数组,切出一部分成为切片
    var a [9]int = [9]int{1, 2,3 ,4, 5, 6, 7,8, 9}
    b := a[0:3]  // 顾头不顾尾, 没有-1,没有步长

    // b []int 中括号中没有东西,就是切片
    // 2 切片定义并赋初值
    var a []int=[]int{1,2,3}
    fmt.Println(a)
    fmt.Println(len(a))
    fmt.Println(cap(a))
    var b []int
    fmt.Println(b)

    //3 切片的修改会影响底层数组,数组的修个也会影响切片
    var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
    var b []int=a[0:3]  //前闭后开
    fmt.Println(a)
    fmt.Println(b)
    a[0]=999
    b[2]=888
    fmt.Println(a)
    fmt.Println(b)

    // 4 切片的长度和容量
    var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
    var b []int=a[2:3]  //前闭后开
    fmt.Println(len(b))  // 3
    //切片容量是7,意思是,可以往里追加值,追加成7个
    fmt.Println(cap(b))  // 从第一个算数组还有几个数

    //5 追加值
    var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
    var b []int=a[2:3]  //前闭后开
    b=append(b,1)
    //b=append(b,11,22,33,44,55)
    fmt.Println(len(b))  // 2
    fmt.Println(cap(b))  // 7
    fmt.Println(b)
    fmt.Println(a)
    //到了数组的尾部,继续追加值
    b=append(b,1,2,3,4,5,6,999)
    fmt.Println(len(b))  // 2+7=9
    fmt.Println(cap(b))  //容量是14 (原来的容量翻倍)
    // 总结1:当切片追加值,超过了切片容量,切片容量会翻倍,在原来容量基础上乘以2
    // 总结2:一旦超过了原数组, 就会重新申请数组,把数据copy到新数组,切片和原数组就没有关系了

    //6 通过make创建切片(底层也依附于数组)
    //3是长度,4是容量
    var a []int=make([]int,3,4)
    fmt.Println(len(a))  // 3
    fmt.Println(cap(a))  // 4
    fmt.Println(a)  // [0 0 0]
    a= append(a, 33)
    fmt.Println(a)  // [0 0 0 33]
    fmt.Println(len(a))  // 4
    fmt.Println(cap(a))  // 4

    //7 切片是引用类型,当参数传递,会修改掉原来的值
    var a []int=[]int{1,2,3}
    fmt.Println(a)
    test3(a)
    fmt.Println(a)

    // 8 多维切片
    var a [][]int=make([][]int,2,3)
    fmt.Println(a)  // [[] []]
    fmt.Println(a[0]==nil)  // true
    //会报错
    //a[0][0]=999
    
    a[0]=make([]int,2,3)
    a[0][1]=999
    fmt.Println(a)  // [[0 999] []]

    //定义并赋初值用的多
    var a [][]int=[][]int{{1,2,3},{4,5,6,7,7,8}}
    //跟上面不一样
    var a [][3]int=[][3]int{{1,2,3},{4,5,6}}
    fmt.Println(a)

    //9 切片的copy
    var a []int=make([]int,3,4)
    var b []int=make([]int,2,6)
    a[0]=11
    a[1]=22
    a[2]=33
    b[0]=999
    fmt.Println(a)
    fmt.Println(b)
    copy(b,a)  // 从a中切出b长度的
    fmt.Println(b)

    //10 切片越界
    var a []int=make([]int,3,4)
    a[0]=11
    a[1]=22
    a[2]=33
    a=append(a,999)
    //中括号取值,只能取到长度值,不能取到容量大小
    fmt.Println(a)  // [11 22 33 999]

}

func test3(a []int)  {
    a[0]=999
    fmt.Println(a)
}

3. map

package main

import "fmt"

func main()  {
    //1 map的定义和使用
    //map[key类型]value类型:key的类型必须可hash,key值:数字,字符串
    var a map[int]string
    fmt.Println(a)
    //map的零值:nil   它是一个引用类型
    if a==nil{
        fmt.Println("我是空的")
    }

    //2 初始化用make
    var a map[int]string=make(map[int]string)
    //如果有,会修改,如果没有,会放入
    a[1]="lqz"
    a[1]="egon"
    a[2]="99"
    fmt.Println(a)

    //3 获取元素
    var a map[int]int=make(map[int]int)
    fmt.Println(a[0])  //取出value值的空值  ""
    a[0]=0
    //a[0] 可以返回两个值,一个是value值(可能为空),另一个是true或false
    v,ok:=a[0]
    fmt.Println(v) // 0
    fmt.Println(ok)  // true

    //4 map 删除元素
    var a map[int]int=make(map[int]int)
    a[1]=11
    a[2]=22
    fmt.Println(a)  //map[1:11 2:22]
    //根据key删(内置函数)
    delete(a,1)
    fmt.Println(a)  //map[2:22]

    //5 map 长度
    var a map[int]int=make(map[int]int)
    fmt.Println(len(a))
    a[1]=11
    a[2]=22
    fmt.Println(len(a))

    //6 map 是引用类型  当参数传递,会修改掉原来的值
    var a map[int]int=make(map[int]int)
    a[1]=11
    test4(a)
    fmt.Println(a)  // map[1:999]

    //7 Map 的相等性
    var a map[string]string=make(map[string]string)
    a["name"]="lqz"
    var b map[string]string=make(map[string]string)
    b["name"]="lqz"
    // 不能这样判断,map只能跟nil比较
    //if a==b {
    //    fmt.Println(111)
    //}
    if a==nil {
    
    }

    //8 循环map
    var a map[string]string=map[string]string{"name":"lqz","age":"19","sex":""}
    //搞不了
    //for i:=0;i<len(a) ; i++ {
    //    fmt.Println(a[i])
    //
    //}
    //range循环
    for k,v:=range a{
        fmt.Println(k)
        fmt.Println(v)
    }

    // 9 map是无序的

}
func test4(a map[int]int)  {
    a[1]=999
    fmt.Println(a)  // map[1:999]

}

 

posted @ 2020-04-22 23:54  Mr沈  阅读(263)  评论(0编辑  收藏  举报