数组、切片、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] }