Go语言数组与切片
数组
数组:是同一种数据类型的固定长度的序列。
数组定义:var a [len]int,比如:var a[5]int
长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1
for i := 0; i < len(a); i++ { }
访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
数组是值类型,因此改变副本的值,不会改变本身的值
arr2 := arr1 arr2[2] = 100
不能改变数组本身的值
package main import ( "fmt" ) func modify(arr [5]int) { arr[0] = 100 fmt.Println("arr",arr) return } func main() { var a [5]int modify(a) for i := 0; i < len(a); i++ { fmt.Println(a[i]) } }
使用指针改变数组的值
package main import ( "fmt" ) func modify(arr *[5]int) { //*[5]int 表示需要传入的值是地址 (*arr)[0] = 100 fmt.Println("arr",arr) return } func main() { var a [5]int modify(&a) for i := 0; i < len(a); i++ { fmt.Println(a[i]) } }
数组的初始化
var age0 [5]int = [5]int{1,2,3} var age1 = [5]int{1,2,3,4,5} var age2 = […]int{1,2,3,4,5,6} var str = [5]string{3:”hello world”, 4:”tom”} #指定具体索引的值
多维数组
var age [5][3]int //定义一个五行三列的数组 var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}} //定义一个两行三列的数组并初始化
简写
var f = [...]int{{7,8,9},{1,2,3}}
多维数组遍历
方式一
package main import ( "fmt" ) func main() { var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}} for k1, v1 := range f { for k2, v2 := range v1 { fmt.Printf("(%d,%d)=%d ", k1, k2, v2) } fmt.Println() } }
package main import ( "fmt" ) func main(){ //var f [2][3]int =[2][3]int{{1,1,2},{3,4,5}} var f = [...][3]int{{1, 2, 3}, {7, 8, 9}} fmt.Println(f) for index,val :=range f{ //fmt.Println(index,val) for k1,k2:=range val{ fmt.Println(index,k1,k2) } } }
方式二
package main import ( "fmt" ) func main(){ //var f [2][3]int =[2][3]int{{1,1,2},{3,4,5}} var arr = [...][3]int{{1, 2, 3}, {7, 8, 9}} fmt.Println(arr) // for index,val :=range f{ // //fmt.Println(index,val) // for k1,k2:=range val{ // fmt.Println(index,k1,k2) // } // } for i := 0; i < len(arr); i++ { for j := 0; j < len(arr[i]); j++ { fmt.Printf("%v ",arr[i][j]) } fmt.Println() } }
切片
切片:切片是数组的一个引用,因此切片是引用类型
切片的长度可以改变,因此,切片是一个可变的数组
切片遍历方式和数组一样,可以用len()求长度
cap可以求出slice最大的容量
切片的定义:var 变量名 []类型,比如 var str []string var arr []int
切片的初始化
切片初始化: var slice []int = arr[start:end] 包含start到end之间的元素,但不包含end var slice []int = arr[0:end]可以简写为 var slice []int=arr[:end] var slice []int = arr[start:len(arr)] 可以简写为 var slice[]int = arr[start:] var slice []int = arr[0, len(arr)] 可以简写为 var slice[]int = arr[:] 如果要切片最后一个元素去掉,可以这么写: slice = slice[:len(slice)-1]
切片的内存布局
通过make来创建切片
var slice []type = make([]type, len) slice := make([]type, len) slice := make([]type, len, cap)
用append内置函数操作切片
slice = append(slice, 10) var a = []int{1,2,3} var b = []int{4,5,6} a = append(a, b…)
运行结果:
[1,2,3,4,5,6]
当我们往 slice中增加元素超过原来的容量时,slice 会自增容量,当现有长度 < 1024 时 cap 增长是翻倍的,当超过 1024,cap 的增长是 1.25 倍增长
For range 遍历切片
var ( a =[]int{1,2,3} b = []int{4,5,6} ) for index,val:=range a{ fmt.Println(index,val) } 0 1 1 2 2 3 3 4 4 5 5 6
切片拷贝
package main import ( "fmt" ) func main(){ var ( s =[]int{1,2,3,45,6,7,8,9} sl = make([]int,20) ) copy(sl,s) fmt.Println(sl) } [1 2 3 45 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0]
string与slice
string底层就是一个byte的数组,因此,也可以进行切片操作
str := "hello world" s8 := str[0:5] fmt.Println(s8) s9 := str[5:] fmt.Println(s9)
string的底层布局
如何改变string中的字符值?
string本身是不可变的,因此要改变string中字符,需要如下操作:
str := “hello world” s := []byte(str) #rune s[0] = ‘o’ str = string(s)
I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我