当前位置:网站首页>【Go ~ 0到1 】 第三天 6月27 slice,map 与 函数
【Go ~ 0到1 】 第三天 6月27 slice,map 与 函数
2022-06-28 08:16:00 【秋日的晚霞】
1. 切片
1.1 切片的定义
切片指向了底层的一个数组
1.2 切片的长度
切片的长度等于切片元素的个数
1.3 切片的容量
切片的容量是底层数组从切片的第一个元素到最后一个元素的数量
//默认情况下 切片的长度 == 容量
s1 := []int{
1, 2, 3}
fmt.Printf("当前切片的长度 %d 切片容量 %d", len(s1), cap(s1))
1.4 切片存在的意义
在Go中,数组一旦创建,大小就固定了无dui法改变数组的长度 因此有了切片
切片的底层是动态数组 可以动态的往数组中添加,删除元素
类似与 Java 中的集合
1.5 创建一个切片
1.5.1 方式一 : 元素个数作为默认容量和长度大小
//默认情况下 切片的长度 == 容量
s1 := []int{
1, 2, 3}
1.5.2 方式二 : 指定切片容量大小和长度
//指定切片的容量和长度大小
ss1 := make([]int, 3, 5)
fmt.Printf("当前切片的长度 %d 切片容量 %d", len(ss1), cap(ss1))
1.5.3 方式三 : 通过数组创建
// 创建切片的方式三 :
//先创建数组
a1 := [...]int{
1, 2, 3}
//将数组转换为切片
sa1 := a1[0:len(a1)]
fmt.Printf("当前切片的长度 %d 切片容量 %d", len(sa1), cap(sa1))
2. 切片扩容
切片一次扩容为上一次 容量*2 当元素长度 >
2.1 append 增加 元素
//默认情况下 切片的长度 == 容量
s1 := []int{
1, 2, 3}
fmt.Printf("当前切片的长度 %d 切片容量 %d", len(s1), cap(s1))
// 添加一个元素 切片容量将增加2倍 长度将增加一
s1 = append(s1, 4)
fmt.Printf("当前切片的长度 %d 切片容量 %d", len(s1), cap(s1))
2.2. 切片的扩容机制
1、当需要的容量超过原切片容量的两倍时,会使用需要的容量作为新容量。
2、当原切片长度小于1024时,新切片的容量会直接翻倍。而当原切片的容量大于等于1024时,会反复地增加25%,直到新容量超过所需要的容量。
上述都是不精确的 容量在计算完毕后 还要考虑到内存的高效率利用,进行内存对齐
2.2. 1需要容量 > old * 2 则 新容量 = 需要
// 情景一 : 如果需要的容量大于当前容量*2
s1 := []int{
0}
fmt.Printf("原始切片的长度 %d 切片容量 %d \n", len(s1), cap(s1))
s1 = append(s1, 1, 2, 3)
fmt.Printf("新切片的长度 %d 切片容量 %d \n", len(s1), cap(s1))
//输出结果 原始切片的长度 1 切片容量 1
// 新切片的长度 4 切片容量 4
2.2.2 需要容量 < old * 2 且 old < 1024 则 新容量 = 原容量 * 2
//情景二 : 如果需要的容量 小于 当前容量 * 2 且 当前容量 少于 1024
s1 := make([]int, 99, 100) // 原有容量大于 1024 则 扩容规则为 oldcap = oldcap *2 则结果应为 200
fmt.Printf("原始切片的长度 %d 切片容量 %d \n", len(s1), cap(s1))
s1 = append(s1, 1, 2, 3)
fmt.Printf("新切片的长度 %d 切片容量 %d \n", len(s1), cap(s1)) //实际结果为 200
2.2.3 需要容量 < old * 2 且 old > 1024 则 新容量 = 原容量 * 1.25
//情景二 : 如果需要的容量 小于 当前容量 * 2 且 当前容量 少于 1024
s1 := make([]int, 1022, 1024) // 原有容量大于 1024 则 扩容规则为 oldcap = oldcap *1.5 则结果应为 1536
fmt.Printf("原始切片的长度 %d 切片容量 %d \n", len(s1), cap(s1))
s1 = append(s1, 1, 2, 3)
fmt.Printf("新切片的长度 %d 切片容量 %d \n", len(s1), cap(s1)) //实际结果为 1536
3. 切片复制
s1 := []int{
1, 2, 3}
s2 := make([]int, 2, 2)
copy(s2, s1) // 参数一: 目的地 参数二 : 来源
fmt.Println(s2)
切片复制时 将根据需要复制元素的切片长度进行复制 如上述代码所示
则 s2 的打印结果为 1,2
4. 获取内存地址值与对应的取值
在 Go 语言中 不存在 对指针的操作 与内存相关的有两个符号 需要记住
4.1 ’ & ’ 获取对象内存地址值
s1 := 10
fmt.Printf("s1 的内存地址为 %v", &s1)
4.2 ’ * ’ 根据内存地址值获取值
mt.Printf("根据内存地址取值 %v", *(&s1))
5. new 函数和 make 函数的用法
两者都是用来申请内存地址的 但 还是有区别的
new 主要用来给基本数据类型申请内存地址 而 make 是用来给 slice, map , chan 申请内存地址的
4. map 的使用
4.1 map 的 创建
//创建一个map
m := make(map[string]int)
//创建一个map
m := make(map[string]int,[容量大小])
4.2 map 添加值
m["张三"] = 19
m["李四"] = 20
m["王五"] = 21
4.3 map 遍历
4.3.1 遍历key,value
//遍历:
for key, value := range m {
fmt.Printf("%v ---- %v \n", key, value)
}
4.3.2 遍历key
//遍历key
for key, _ := range m {
fmt.Println(key)
}
4.3.3 遍历 value
//遍历value
for _, value := range m {
fmt.Println(value)
}
4.4 根据 key 删除 value
//根据key删除 value
delete(m,"张三")
4.5 判断key是否存在
约定俗成使用 ok 标识一个 key是否存在
//判断key是否存在
i, ok := m["张三1"]
if !ok {
fmt.Printf("%v 不存在当前key \n", m)
} else {
fmt.Printf("当前key对应的值为 %v \n", i)
}
5. 函数
5.1 什么是函数
函数时对代码的封装 把一段代码抽取出来, 给它起个名字 每次使用的时候只需要调用函数名即可 提高了代码的利用率
5.2 函数的定义
func mymethod(x int, y int) (ret int) {
return x + y
}
注意事项 :
形参列表如果连续多个参类型数一致时,只需要写最后一个参数的类型 ,其他参数的类型可以省略
如果 我们对返回值进行了命名(等同于声明一个局部变量), 可以直接写一个return
func mymethod1(x,y int)(sum int) {
sum = x + y
return
}
- 多个返回值时,同样也可以对返回值进行命名
func mymethod1(x, y int) (sum int, del int) {
sum = x + y
del = x - y
return
}
5.3 匿名函数
如果一个函数我们只想使用一次,那么可以使用匿名函数
//匿名函数赋值给一个变量
mn1 := func(x, y int) (int) {
return x + y
}
fmt.Println(mn1(1, 9))
5.4 全局匿名函数
//全局的匿名函数 赋值给一个变量
var (
m = func(x, y int) int {
return x + y
}
)
end 练习
1.统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1
str := "what do you want do what"
split := strings.Split(str, " ")
//遍历 字符切片 往 map 集合中 存
m1 := make(map[string]int)
for _, word := range split {
//判断字符串是否已经存在
_, ok := m1[word]
if !ok {
//不存在
m1[word] = 1
} else {
//已经存在
m1[word] = m1[word] + 1
}
}
//打印结果
fmt.Println(m1)
边栏推荐
- How to choose an account opening broker? Is it safe to open an account online?
- AI首席架构师8-AICA-高翔 《深入理解和实践飞桨2.0》
- MySQL row format parsing
- Sword finger offer 03 Duplicate number in array
- NLP sequence can completely simulate human brain intelligence
- Uvcgan: unt vision transformer cycle-consistent Gan for unpropared image-to-image translation
- 设置网页的标题部分的图标
- 城联优品向英德捐赠抗洪救灾爱心物资
- Solve NPM err! Unexpected end of JSON input while parsing near
- Upgrade HDP spark to spark 2.4.8 without upgrading ambari
猜你喜欢

Almost Union-Find(带权并查集)

B_ QuRT_ User_ Guide(27)

探讨gis三维系统在矿山行业中的应用

Two tips for block level elements

Redis master-slave structure and application scenarios

Eslint 语法监测关闭

SQL Master slave Replication Build

Usage record of Xintang nuc980: self made development board (based on nuc980dk61yc)

Login common test case

块级元素上下左右居中的两个小技巧
随机推荐
Children's unit of 2022 Paris fashion week ended successfully at Wuhan station on June 19
How redis solves cache avalanche, breakdown and penetration problems
Airflow2 configuration windows azure SSO details based on oauth2 protocol
Is it reliable for flush to register and open an account? Is it safe?
Trailing Zeroes (II)
Three step problem of leetcode
Selenium+chromedriver cannot open Google browser page
How to use redis to solve concurrency problems
Installing MySQL under Linux
块级元素上下左右居中的两个小技巧
你了解TCP協議嗎(二)?
How to choose an account opening broker? Is it safe to open an account online?
SLAM中常用的雅克比矩阵J
SQL Master slave Replication Build
【学习笔记】最短路 +生成树
redis02——一篇终结redis的五种数据类型操作命令(可学习、复习、面试、收藏备用)
Two tips for block level elements
[JS] - [DFS, BFS application] - learning notes
Is it reliable for the top ten securities companies to register and open accounts? Is it safe?
Redis cerebral fissure