Golang Array and Slice

Posted 潇洒的云世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang Array and Slice相关的知识,希望对你有一定的参考价值。

刚开始学习Golang的时候分不清Array(数组)Slice(切片)的区别,在Python中是没有单独的Slice类型,而且GolangArraySlice定义非常相似,如下:

 

Array定义(Array需要写len长度或者,或者用表示)

(1)var arr [3]int

(2)arr := [3]int{1,2,3}

(3)arr := […]int{1,2,3,4}

 

Slice定义(不用写len长度,也可以设定lencapacity)

(1)  var sli []int

(2)  sli := []int{1,2,3}

(3)  sli := arr[2:3]  //通过Array切片

(4)  sli := make([]int,3,6)//设定len3capacity6

 

对于Slice还有额外的appendcopy方法,用来对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

可以看到我们定义了一个长度为3slicecapacity6,默认sli的内容为[0 0 0],在对原有sli append后长度变为了8capacity扩占了一倍,如果是不设定capacityslice,当内容超过原本的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循环对sli1sli2插入数据,然后将sli2 copysli1,可以看到新的sli1,为[1 2 2]sli2的原来两个值覆盖了sli1最前面原来的两个值,注意copy前面为destination slice,后面为source slice

==============================

 



将元素Popslice没有单独将包含元素删除的方法,只能通过切片获得为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切片得到sli1sli2,这两个Slice的值最初是一样的,我们在sli2后添加1,2,3,4,操作完后打印发现arr1没有改变,我们在sli1后添加1,发现arr1最后一位变成了1,就说明SliceArray的镜像,Slice的操作有可能会改变array,当改变的范围在ArrayCapacity范围内,那么Array就会发生改变,如果超过了ArrayCapacityArray就不会改变

==============================



 

ArraySlice的值传递和索引传递,我们拿下面这个例子说明

==============================

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演示

golang 使用Golang的Array类型的PostgreSQL演示

golang之array

Https and Golang

golang之 Array(数组)

golang切片