map切片

160 阅读3分钟

切片的创建方式

  1. 从数组或者切片上切取获得
  2. 直接声明切片 : var name []Type // 不同于数组, []没有数字
  • 切片语法

arr [start : end] 或者 slice [start : end] // start: 开始索引 end:结束索引

  • 切片特点
  1. 左闭右开 [ )
  2. 取出的元素数量为:结束位置 - 开始位置;
  3. 取出元素不包含结束位置对应的索引,切片最后一个元素使用 slice[len(slice)]获取;
  4. 当缺省开始位置时,表示从连续区域开头到结束位置;当缺省结束位置时,表示从开始位置到整个连续区域末尾;两者同时缺省时,与切片本身等效;

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 // 最大长度(容量),也就是切片开始位置到数组的最后位置的长度

}

image.png

make函数

如果需要动态地创建一个切片,可以使用 make() 内建函数。

make([]Type, size, cap) //切片类型,长度,容量

类型和长度必须要有

append切片操作

image.png

  • 扩容机制

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"