golang数组与切片

数组的特点:

1、长度固定,无法扩容 (记住)

2、数组是值类型,也就是说在作为参数时,函数体中无法修改传入的数组的值

数组定义的方式:

var a[3] int    //初始值为0的长度为3的整型数组

a := [3]int{1,2,3}  //定义并初始化长度为3的整型数组

a := [3]int{1,2}   //未提供初始值的初始为0,[1,2,0]

a := [...] int {1,2,3}   //跟2一样,区别是长度由编译器自动推断

a := [4]int{4, 3:10}  //指定索引位置的初始值 [4,0,0,10]

a := [...] int { 99 : -1}  //长度为100,最后一个是-1,其他是0

a := [...]int{3, 3:10, 5 }  //指定索引位置的初始值,同时也决定了长度, [3,0,0,10,5]

  

切片特点:

1、长度不固定、可以追加元素(append),在追加时可能使切片的容量增大

2、切片是引用类型

切片slice的数据结构:一个指向真实array数组地址的指针ptr,slice的长度len和容量cap

type Slice struct {
     ptr unsafe.Pointer   //Array Pointer
     len int                    // slice len
     cap int                   // slice capacity
}

声明一个切片

s := []int{1,2,3}   //初始值是1,2,3   cap=len=3
s := arr[:]            //初始化切片为arr的引用
s := arr[startIndex:endIndex]  //将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
s := arr[startIndex:]   //缺省endIndex时将表示一直到arr的最后一个元素
s := arr[:endIndex]  //缺省startIndex时将表示从arr的第一个元素开始
s :=make([]int,len,cap)  //通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片
var numbers []int   // 一个切片在未初始化之前默认为 nil,长度为 0

  

当在使用 append 的时候,如果 cap==len 了这个时候就会新开辟一块更大内存,然后把之前的数据复制过去,ptr所指向的地址指向新的内存地址

在实际使用中,我们最好事先预期好一个cap,这样在使用append的时候可以避免反复重新分配内存复制之前的数据,减少不必要的性能消耗。

s := []int{1, 2, 3, 4, 5}
fmt.Printf("len:%d cap: %d array ptr: %v \n",
   len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))
fmt.Println("Array:", s)

s1 := s[:3]

s[0] = 7
fmt.Printf("len:%d cap: %d array ptr: %v \n",
   len(s1), cap(s1), *(*unsafe.Pointer)(unsafe.Pointer(&s1)))
fmt.Println("Array", s1)

  

结果: 可以看出

len:5 cap: 5 array ptr: 0xc0420684b0 
Array: [1 2 3 4 5]
len:3 cap: 5 array ptr: 0xc0420684b0 
Array [7 2 3] 

可以看出s1跟s的地址是一样的,而且改变s[0]的值,s1[0]也会跟着改变,因为他们都是引用着相同的底层数组

猜你喜欢

转载自www.cnblogs.com/coder-886/p/9845461.html