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