切片的创建方式
- 从数组或者切片上切取获得
- 直接声明切片 :
var name []Type// 不同于数组, []没有数字
- 切片语法
arr [start : end] 或者 slice [start : end] // start: 开始索引 end:结束索引
- 切片特点
- 左闭右开 [ )
- 取出的元素数量为:结束位置 - 开始位置;
- 取出元素不包含结束位置对应的索引,切片最后一个元素使用
slice[len(slice)]获取;- 当缺省开始位置时,表示从连续区域开头到结束位置;当缺省结束位置时,表示从开始位置到整个连续区域末尾;两者同时缺省时,与切片本身等效;
var arr = [5]int{10, 11, 12, 13, 14}
var s1 = arr[1:4]
fmt.Println(s1, reflect.TypeOf(s1)) // [11 12 13] []int
var s2 = arr[2:5] fmt.Println(s2, reflect.TypeOf(s2)) // [12 13 14]
var s3 = s2[0:2]
值类型和引用类型
基本数据类型(int,float,bool,string)以及数组和struct都属于值类型。
- 值类型
特点:变量直接存储值,内存通常在栈中分配,栈在函数调用完会被释放。值类型变量声明后,不管是否已经赋值,编译器为其分配内存,此时该值存储于栈上。
*当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝,可以通过 &i 获取变量 i 的内存地址。此时如果修改某个变量的值,不会影响另一个。
- 引用类型
指针、slice,map,chan,interface等都是引用类型。
特点:变量通过存储一个地址来存储最终的值。内存通常在堆上分配,通过GC回收。
引用类型必须申请内存才可以使用,new()和make()是给引用类型申请内存空间。
切片原理
切片的构造根本是对一个具体数组通过切片起始指针,切片长度以及最大容量三个参数确定下来的
type Slice struct {
Data uintptr // 指针,指向底层数组中切片指定的开始位置
Len int // 长度,即切片的长度
Cap int // 最大长度(容量),也就是切片开始位置到数组的最后位置的长度
}
make函数
如果需要动态地创建一个切片,可以使用 make() 内建函数。
make([]Type, size, cap) //切片类型,长度,容量
类型和长度必须要有
append切片操作
- 扩容机制
1、每次 append 操作都会检查 slice 是否有足够的容量,如果足够会直接在原始数组上追加元素并返回一个新的 slice,底层数组不变,但是这种情况非常危险,极度容易产生 bug!而若容量不够,会创建一个新的容量足够的底层数组,先将之前数组的元素复制过来,再将新元素追加到后面,然后返回
新的 slice,底层数组改变而这里对新数组的进行扩容
2、扩容策略:如果切片的容量小于 1024 个元素,于是扩容的时候就翻倍增加容量。上面那个例子也验证了这一情况,总容量从原来的4个翻倍到现在的8个。一旦元素个数超过 1024 个元素,那么增长因子就变成 1.25 ,即每次增加原来容量的四分之一。
进行增删改查
var customer1 = map[string]string{"name": "yuan", "age": "22"}
var customer2 = map[string]string{"name": "rain", "age": "30"}
var customer3 = map[string]string{"name": "alvin", "age": "32"}
var customers = []map[string]string{customer1, customer2, customer3}
var newCustomer = map[string]string{"name": "eric", "age": "32"}
//增加
var addCustomers = append(customers, newCustomer)
//查看
for _, customer := range customers {
fmt.Printf("客户名字:%-8s,年龄:%s-8\n", customer["name"], customer["age"])
}
//删除
删除的逻辑就是:比如要删除第3位的元素,就取前三位的切片(左闭右开),然后将第四位到最后的元素展开塞入这个切片中。
`append(customer[:index],customer[index+1:]`
var RemoveCustomer = append(customers[:1], customers[2:]...)
//修改
customer := customers[1]
customer["name"] = "RAIn"
customer["age"] = "33"