数组与切片
数组
数组长度固定,数组本身的方法也少,在Go语言内数组使用没那么灵活,所以少用。而且Go语言内不支持负向索引,所以相比其他语言Go语言的数组特性也少了些。
func main() { var arr [3]string = [3]string{"你好", "晚安", "早安"} fmt.Println(arr) fmt.Println(arr[0]) //你好 fmt.Println(arr[1]) //晚安 fmt.Println(arr[2]) //早安 fmt.Println(len(arr)) //看arr数组的长度 fmt.Println(arr[len(arr)-1]) //这样也可以输出早安 //如果是python的话,要取数组最后一个可以直接用arr[-1],因为python支持负向索引 }
- slice(切片)一般多用,因为是动态增长的,功能也更灵活。
- 数组的长度是数组类型的一部分。
声明了一个数组,如果要对数组进行操作,可以先实例化。这样做可以避免数组为空。
func main() { var arr []string = []string{} //虽然无内容,但数组不为空 //或者 var arr []string arr = make([]string,0) //长度是0 //或者 arr := make([]string,0) //长度是0 //数组也可以用省略写法 var arr1 = []string{} arr2 := []string{} }
Go语言中,数组是值类型而不是引用类型,改变新值不会改变旧值。
func copyarr() { //Go语言中,数组是值类型而不是引用类型,改变新值不会改变旧值 arr := [...]string{"1", "String0", "String1"} copyarr := arr copyarr[0] = "String" //修改开头的内容 fmt.Println(arr) //"1", "String0", "String1" fmt.Println(copyarr) //"String", "String0", "String1" }
切片
- 切片是对数组一个连续片段的引用,所以切片是一个引用类型。(切片是由数组切出来的,这也就意味着切片本身不具有任何数据,只是对现有数组进行引用。)
- 每个切片值都会将其数组作为其底层的数据结构。
Go语言中可以使用
make函数
去创建指定长度、指定容量的切片。(make声明方式,name := make([]Type,size,cap)
)func main() { numList := make([]int, 3, 5) fmt.Println(numList) //指针:是指向第一个切片元素对应的底层数组元素的地址。(切片第一个元素不一定是数组第一个元素) //长度:切片中的元素个数 //容量:从切片开始的位置到底层数据的结束位置 }
切片可以动态的增添、删减、修改其中的内容,但只能增添、删减、修改与切片同类型的值。(其实数组也是)
增添:
func appendslice() { var s = []string s = append(s, "你好") s = append(s, "早安","晚安") s = append(s, []string{"早上好", "再见"}...) //追加一个切片,解应用添加 fmt.Println(s[0]) //输出你好 //但是记住,每次这样添加扩容,是扩容每次添加的上一次的容量(cap)的两倍,因此后面这样添加可能会有扩容了但是没用,导致性能损伤 //多维切片和数组建立几乎一致,但是[]里不用输入容量 }
删除:
func deleteslice() { s := []string{"1", "2", "3", "4", "5", "6"} fmt.Println(s) //删除开头 //方法一: s = s[1:] //删除开头一个元素,想要删除开头N个元素可以s = s[N:] fmt.Println("开头删除:", s) //方法二: s = append(s[:0], s[1:]...) //删除开头的1个元素,想要删除开头N个元素可以s = append(s[:0], s[N:]...) fmt.Println(s) //方法三: s = s[:copy(s, s[1:])] //用copy的方式删除开头1个元素,想要删除开头N个元素可以s = s[:copy(s, s[N:])] fmt.Println(s) //中间开始删除 //方法一: //s = append(s[:i], s[i+1:]...) // 删除中间1个元素 //s = append(s[:i], s[i+N:]...) // 删除中间N个元素 //方法二: //s = s[:i+copy(a[i:], s[i+1:])] // 删除中间1个元素 //s = s[:i+copy(a[i:], s[i+N:])] // 删除中间N个元素 //例如 s1 := []string{"1", "2", "3", "4", "5", "6"} s1 = append(s1[:1], s1[2:]...) // 删除中间1个元素 fmt.Println("中间删除:", s1) //从尾部删除 //s2 = s2[:len(s)-1] // 删除尾部1个元素 //s2 = s2[:len(s)-N] // 删除尾部N个元素 s2 := []string{"1", "2", "3", "4", "5", "6"} s2 = s2[:len(s2)-1] fmt.Println("尾部删除:", s2) }
- 如果定义了一个切片,但未赋值,则会报错。
切片从一个数组中切出来
func main() { arr := [5]string{"1", "2", "3", "4", "5"} var slice = arr[1:4] //切片中不包含结尾位置的元素,也就是取值到 结束位置-1。 //如果冒号左右不写位数,则切片默认含有数组全部元素 fmt.Println(slice) //像arr,其长为5,则冒号左右可以是0,1,2,3,4,5。5即最右,0即最左。 }
切片可以通过
len()函数
来看切片的长度,通过cap()函数
来看切片的大小func main() { s := make([]int, 3, 5) fmt.Println(len(s)) fmt.Println(cap(s)) }
数组里说过,数组是值类型,不是引用类型。那切片就相反,切片是引用类型。
func main() { arr := [...]string{"1", "2", "3", "4", "5"} var num = arr[:] fmt.Println(arr) fmt.Println(num) num[0] = "10" //因为切片是引用,所以对切片内元素进行改变会应用到数组中,切片变则数组变 fmt.Println(arr) fmt.Println(num) }
切片排序,可以用Go语言的默认
sort()函数
进行排序。func main() { s1 := []int{3, 2, 1, 5, 4} sort.Ints(s1) //sort默认升序排序 fmt.Println(s1) sort.Sort(sort.Reverse(sort.IntSlice(s1))) //降序 fmt.Println(s1) }
评论(0)