Golang Array and Slice
Posted 潇洒的云世界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang Array and Slice相关的知识,希望对你有一定的参考价值。
刚开始学习Golang的时候分不清Array(数组)和Slice(切片)的区别,在Python中是没有单独的Slice类型,而且Golang的Array和Slice定义非常相似,如下:
Array定义(Array需要写len长度或者,或者用…表示)
(1)var arr [3]int
(2)arr := [3]int{1,2,3}
(3)arr := […]int{1,2,3,4}
Slice定义(不用写len长度,也可以设定len或capacity)
(1) var sli []int
(2) sli := []int{1,2,3}
(3) sli := arr[2:3] //通过Array切片
(4) sli := make([]int,3,6)//设定len为3,capacity为6
对于Slice还有额外的append和copy方法,用来对slice中添加新的数据,如果我们是通过Array切片得到的Slice,和将一个sclie中的数据copy到另一个slice中并覆盖,我们来试一下
Append方法
==============================
package main
import "fmt"
func main(){
sli := make([]int,3,6)
fmt.Printf("sli is %d,len(sli) is%d,and cap(sli) is %d\n",sli,len(sli),cap(sli))
sli = append(sli,1,2,3,4,5)
fmt.Printf("sli is %d,len(sli) is%d,and cap(sli) is %d",sli,len(sli),cap(sli))
}
输出结果为
sli is [0 00],len(sli) is 3,and cap(sli) is 6
sli is [0 0 0 12 3 4 5],len(sli) is 8,and cap(sli) is 12
可以看到我们定义了一个长度为3的slice,capacity为6,默认sli的内容为[0 0 0],在对原有sli append后长度变为了8,capacity扩占了一倍,如果是不设定capacity的slice,当内容超过原本的capacity时,capacity也会按一倍一倍扩展
==============================
Copy方法
==============================
package main
import "fmt"
func main(){
sli1 := make([]int,3,6)
sli2 := make([]int,2,8)
for i := 0 ; i < 3 ; i++{
sli1[i] = i
}
for i := 0 ; i < 2 ; i++{
sli2[i] = i + 1
}
fmt.Printf("sli1 is%d,len(sli1)is %d,cap(sli1) is %d\n",sli1,len(sli1),cap(sli1))
fmt.Printf("sli2 is %d,len(sli2)is%d,cap(sli2) is %d\n",sli2,len(sli2),cap(sli2))
copy(sli1,sli2)
fmt.Printf("sli1 is%d,len(sli1)is %d,cap(sli1) is %d\n",sli1,len(sli1),cap(sli1))
fmt.Printf("sli2 is%d,len(sli2)is %d,cap(sli2) is %d",sli2,len(sli2),cap(sli2))
}
输出结果为
sli1 is [0 1 2],len(sli1)is3,cap(sli1) is 6
sli2 is [12],len(sli2)is 2,cap(sli2) is 8
sli1 is [1 22],len(sli1)is 3,cap(sli1) is 6
sli2 is [12],len(sli2)is 2,cap(sli2) is 8
我们通过一个for循环对sli1和sli2插入数据,然后将sli2 copy到sli1,可以看到新的sli1,为[1 2 2],sli2的原来两个值覆盖了sli1最前面原来的两个值,注意copy前面为destination slice,后面为source slice
==============================
将元素Pop,slice没有单独将包含元素删除的方法,只能通过切片获得为Reslice操作,如下
==============================
package main
import (
"fmt"
)
func main(){
sli1 := []int{1,2,3,4,5,6}
fmt.Printf("sli1 is%d,len(sli1)is %d,cap(sli1) is %d\n",sli1,len(sli1),cap(sli1))
sli1 = append(sli1[:2],sli1[3:]...)
fmt.Printf("sli1 is%d,len(sli1)is %d,cap(sli1) is %d\n",sli1,len(sli1),cap(sli1))
}
输出结果为
sli1 is [1 2 3 45 6],len(sli1)is 6,cap(sli1) is 6
sli1 is [1 2 4 56],len(sli1)is 5,cap(sli1) is 6
我们可以用切片将sli1[2]去除,用append连接两个slice,可以看到sli1虽然len变短了,但是capacity没有改变,注意append用来添加切片时需要在后面添加…
==============================
如果我们是通过Array创建的Slice,我们操作的时候需要注意,这时候的Slice相当于Array的镜像,修改Slice会影响原来的Array,导致无法想象的结果,测试案例如下:
==============================
package main
import "fmt"
func main(){
arr1 := [...]int{1,2,3,4,5,6,7,8,9,10}
sli1 := arr1[8:9]
sli2 := arr1[8:9]
fmt.Printf("arr1 is %d,sli1 is%d\n",arr1,sli1)
sli2 = append(sli1,1,2,3,4)
fmt.Printf("arr1 is %d,sli1 is%d\n",arr1,sli2)
sli1 = append(sli1,1)
fmt.Printf("arr1 is %d,sli1 is%d",arr1,sli1)
}
输出结果为
arr1 is [1 2 3 45 6 7 8 9 10],sli1 is [9]
arr1 is [1 2 3 45 6 7 8 9 10],sli1 is [9 1 2 3 4]
arr1 is [1 2 3 45 6 7 8 9 1],sli1 is [9 1]
可以看到我们将arr1切片得到sli1和sli2,这两个Slice的值最初是一样的,我们在sli2后添加1,2,3,4,操作完后打印发现arr1没有改变,我们在sli1后添加1,发现arr1最后一位变成了1,就说明Slice是Array的镜像,Slice的操作有可能会改变array,当改变的范围在Array的Capacity范围内,那么Array就会发生改变,如果超过了Array的Capacity,Array就不会改变
==============================
Array和Slice的值传递和索引传递,我们拿下面这个例子说明
==============================
package main
import "fmt"
const len = 3
func arrFunc(arr [len]int){
arr[0] = 3
}
func sliFunc(sli []int){
sli[0] = 3
}
func main(){
arr1 := [len]int{1,2,3}
arrFunc(arr1)
fmt.Printf("arr1 is %d\n",arr1)
sli1 := []int{1,2,3}
sliFunc(sli1)
fmt.Printf("sli1 is %d",sli1)
}
输出结果为
arr1 is [1 2 3]
sli1 is [3 2 3]
可以看到Array arr1的值在经过函数操作后并没有改变,而Slice sli1的操作在经过函数操作后发生了改变,因为Array在传递时时copy了一份值,并没有改变原始数据,而Slice函数操作时是传递的索引,会改变原始数据,当然我们可以使用指针,同样来改变Array的原始数据,如下
package main
import "fmt"
const len = 3
func arrFunc(arr *[len]int){
arr[0] = 3 //此处还可以写成(*arr)[0] =3
}
func main(){
arr1 := [len]int{1,2,3}
arrFunc(&arr1)
fmt.Printf("arr1 is %d\n",arr1)
}
输出结果为
arr1 is [3 2 3]
以上是关于Golang Array and Slice的主要内容,如果未能解决你的问题,请参考以下文章
golang 使用Golang的Array类型的PostgreSQL演示