Golang中的切片与数组及区别详解

  

在golang中有数组和切片两种数据结构,片是基于数组的实现,是长度动态不固定的数据结构,本质上是一个对数组字序列的引用,提供了对数组的轻量级访问。那么我们今天就给大家详细介绍下golang中的切片与数组,

  

  

,,,数组是一种具有固定长度的基本数据结构,在golang中与C语言一样数组一旦创建了它的长度就不允许改变,数组的空余位置用0填补,不允许数组越界。

  

,,,,

  

<>强,,,,1 .创建数组:

        函数main () {   var arr1=[…int){1, 2, 3, 4}//[…]默认为元素的数量即为数组的长度   fmt.Println (len (arr1))//4   arr1[4]=5//恐慌数组越界   fmt.Println (arr1)   var arr2=[10] int {1, 2, 3, 4}   fmt.Println (arr2)//(1 2 3 4 0 0 0 0 0 0]   }      

<强> 2。数组是值拷贝传递:

        函数main () {   var arr=[10] int {4、5、7、11、8、9}   fmt.Println (arr)//(4、5、7、11、8, 9, 0, 0, 0, 0)//验证数组是值拷贝传递   AddOne (arr)   fmt.Println (arr)//(4、5、7、11、8, 9, 0, 0, 0, 0)   }   func AddOne (arr [10] int) {   arr [9]=999999   fmt.Println (arr)//(4、5、7、11、8, 9, 0, 0, 0, 999999]   }      之前      

  

,,,,1 .首先看看切片的源码结构:

        类型片结构{   数组unsafe.Pointer   int len   帽int   }   之前      

片是一个特殊的引用类型,但是它自身也是个结构体

  

,,,,,,属性len表示可用元素数量,读写操作不能超过这个限制,不然就会恐慌

  

,,,,,,属性限制表示最大扩张容量,当然这个扩张容量也不是无限的扩张,它是受到了底层数组数组的长度限制,超出了底层数组的长度就会恐慌

  

,,,, <强> 2.片的创建:

        函数main () {   var arr=[…] int {0, 1, 2, 3, 4, 5, 6}   slice1:=arr[1:4:5]//{低:高:max}最多再扩张一个元素//max超出len (arr)//slice2:=arr[1:4:7]//恐慌   fmt.Println (slice1)//(1、2、3)   slice3:=slice1[1:3:4]//[2、3]大于4会恐慌   fmt.Println (slice3)   }      之前      

上面代码中创建了一个长度为7的数的arr组,同时创建一个基于数组arr的切片slice1,切片引用了数组的指数=1到指数=3之间的元素,同时也允许切片最大扩张1个元素大小的空间。如果这个扩张空间大于7那么程序就会恐慌。最后创建了一个基于slice1延申的一个切片slice2,它引用了切片的指数=1到指数=3之间的元素,由于slice1最大扩容1个元素,因此slice2也最多扩容一个元素,超过了会恐慌。

  

 Golang中的切片与数组及区别详解

  

,,,创建基于底层数组的片,其帽取值在:len<=cap<=len (arr)之间

  

,,,创建基于一个切片的片,其帽取值在:len (slice1) & lt;=cap<=帽(slice1)之间

  

<强>,,3.片使用使创建

        函数main () {   var片=使(int [] 3 5)//len=3,帽=5   fmt.Println(片)//(0,0,0)   slice2:=片(5)://片实现了对切片的扩容,切片长度变为5   fmt.Println (slice2)//(0, 0, 0, 0, 0)   }      

, <强> 4。切片作为参数传递

        函数main () {   var片=使(int [] 3 5)//len=3,帽=5   fmt.Println(片)//(0,0,0)   slice2:=片(5)://片实现了对切片的扩容,切片长度变为5   fmt.Println (slice2)//(0, 0, 0, 0, 0)   片[0]=999//这里片和切片的指数=0位置都是999年因为他们引用的底层数组的指数=0位置都是999   fmt.Println(片)   fmt.Println (slice2)   AddOne(片)//(8888,0,0)   fmt.Println(片)//(8888,0,0)   fmt.Println (slice2)//(8888, 0, 0, 0)   }   func AddOne (int []) {   s [0]=8888   fmt.Println (s)   }      之前      

因为切片是个引用类型,所以它作为参数传递给函数,函数操作的实质是底层数组

  

        函数main () {   var arr=[…] int {1, 2, 3, 4}   fmt.Println (arr)//(1、2、3、4)   片:=arr [:]   fmt.Println(片)//(1、2、3、4)   片=append(片、int[]{5 6 7}…)//此时切片的引用地址已经发生改变了,它引用的底层数组再也不是加勒比海盗了,而是一个新的数组newarr [1, 2, 3, 4, 5, 6, 7]   fmt.Println(片)//[1,2,3,4,5,6,7]//验证片引用的地址已经发生改变   片[0]=666   fmt.Println (arr)//(1、2、3、4)   fmt.Println(片)//[666年2、3、4、5、6、7)   }

Golang中的切片与数组及区别详解