golang数据二(切片)

  

在项目开发过程中,更多的场景是需要一个长度可以动态更新的数据存储结构,切片本身并非是动态数组或数组指针,他内部通过指针引用底层数组,并设定相关属性将数据读写操作限定在指定区域内。比如:

/运行/slice.go      type  slice  struct  {   array  unsafe.Pointer   len , int   cap , int   }

切片有两种基本初始化方式:

切片可以通过内置的让函数来初始化,初始化时len=帽,一般使用时省略帽参数,默认和len参数相同,在追加元素时,如果容量上限不足时,将按len的2倍动态扩容。

通过数组来初始化切片,以开始和结束索引位置来确定最终所引用的数组片段。

//制造([]T, len,, cap),//T是切片的数据的类型,len表示长度上限表示能力   {   ,,,s :=,使(int [], 5),,,,,,//len:, 5,,帽:5   ,,,s :=,使(int [] 5 10),,,,//len:, 5,,帽:10   ,,,s :=, int [] {1,2,3}   },      {   ,,,arr :=, int […] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}   ,,,s1 :=, arr [:]   ,,,s2 :=, arr [2:5]   ,,,s3 :=, arr [2:5:7]   ,,,s4 :=, arr [4:]   ,,,s5 :=, arr [4]   ,,,s6 :=, arr [4:6):      ,,,fmt.Println (“s1: s1, len (s1),帽(s1))   ,,,fmt.Println (“s2: s2, len (s2),帽(s2))   ,,,fmt.Println (“s3: s3,, len (s3),帽(s3))   ,,,fmt.Println (“s4: s4, len (s4),帽(s4))   ,,,fmt.Println (“s5, s5:,“, len (s5),帽(s5))   ,,,fmt.Println (“s6:,“s6, len (s6),帽(s6))   }   输出:   s1:,, (0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 10, 10   s2:,, (2, 3, 4), 3, 8   s3:, (2, 3, 4), 3, 5   s4:,, 4, 5, 6, 7, 8, 9), 6, 6   s5:,, (0, 1, 2, 3], 4, 10   s6:,, (0, 1, 2, 3], 4, 6

通过上例说明帽是表示切片所引用数组片段的真实长度,len是表示已经赋过值的最大下标(索引)值加1。

注意下面两种初始化方式的区别:

{   ,,,var  a  int []   ,,,b :=, int [] {}   ,,,fmt.Println (a==nil, b==nil)      ,,,fmt.Printf(“一个:% # v \ n”,, (* reflect.SliceHeader) (unsafe.Pointer (,)))   ,,,fmt.Printf (" b: % # v \ n”,, (* reflect.SliceHeader) (unsafe.Pointer(和b)))   ,,,fmt.Printf (“a  size  % d \ n”,, unsafe.Sizeof (a))   ,,,fmt.Printf (“b  size  % d \ n”,, unsafe.Sizeof (b))   }   输出:   true 假   答:,,reflect.SliceHeader{数据:0 x0, Len: 0,,帽:0}   b:,, reflect.SliceHeader{数据:0 x5168b0, Len: 0,,帽:0}   a  size  24   b  size  24   说明:   1只变量b的内部指针被赋值,即使该指针指向了runtime.zerobase,但它依然完成了初始化操作   2只变量一个表示一个未初始化的切片对象,切片本身依然会分配所需的内存

切片之间不支持逻辑运算符,仅能判断是否为nil,比如:

{   ,,,var  a  int []   ,,,b :=, int [] {}   ,,,fmt.Println (a==b),//invalid 操作:,a ==, b  (slice 还要only  be  compared 用零)   }

<强>

在原切片的基础上进行新建片、新建的片依旧指向原底层数组,新创建的片不能超出原片

的容量,但是不受其长度限制,并且如果修改新建部分的值,对所有关联的切片都有影响,比如:

{   ,,,s :=,[]字符串{“a”、“b”、“c”,“d”,“e”,“f”,“g”}      ,,,s1 :=, s [1:3],,,,,,,//b, c   ,,,fmt.Println (s1, len (s1),帽(s1))   ,,,s1_1 :=, s1 [2:5],,,,,,,//c, d, e   ,,,fmt.Println (s1_1, len (s1_1),帽(s1_1))   }   输出:   (b  c), 2, 6   [d  e  f], 3, 4

<强>

向切片尾部追加数据,返回新的切片对象;数据被追加到原底层数组,如果超出帽限制,则为新切片对象重新分配数组,新分配的数组帽是原数组上限的2倍,比如:

{   ,,,s :=, (int [] 0 5)   ,,,s =,附加(s ,, 1)   ,,,s =,附加(s ,, 2、3、4、5)   ,,,fmt.Printf (“% p, v %,, % d \ n”,,,,,帽(s))   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

golang数据二(切片)