当前位置:网站首页>【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)
边栏推荐
- 小艺人黄鑫洋受邀参加巴黎时装周儿童单元武汉站
- Tree
- Image translation /transformer:ittr: unpaired image to image translation with transformers
- cuda和cudnn和tensorrt的理解
- 三角变换公式
- [shangpinhui] project notes
- Redis02 -- an operation command of five data types for ending redis (it can be learned, reviewed, interviewed and collected for backup)
- 【学习笔记】差分约束
- [JS] - [DFS, BFS application] - learning notes
- Set<String>
猜你喜欢
Eslint syntax monitoring off
你了解TCP协议吗(二)?
Reverse mapping of anonymous pages
Kubernetes notes and the latest k3s installation introduction
AI首席架构师8-AICA-高翔 《深入理解和实践飞桨2.0》
B_QuRT_User_Guide(26)
找合适的PMP机构只需2步搞定,一查二问
2022巴黎时装周儿童单元6.19武汉站圆满落幕
Build an integrated kubernetes in Fedora
Three step problem of leetcode
随机推荐
Anniversary party
Devops foundation chapter Jenkins deployment (II)
MySQL implements transaction persistence using redo logs
Do you know TCP protocol (2)?
How redis solves cache avalanche, breakdown and penetration problems
The preliminary round of the sixth season of 2022 perfect children's model Foshan competition area came to a successful conclusion
How to use redis to solve concurrency problems
Unity - use of API related to Pico development input system ---c
Not so Mobile
图像翻译:UVCGAN: UNET VISION TRANSFORMER CYCLE-CONSISTENT GAN FOR UNPAIRED IMAGE-TO-IMAGE TRANSLATION
Trailing Zeroes (II)
RAC enable archive log
The Falling Leaves
Trigonometric transformation formula
Redis cluster deployment and application scenarios
NLP sequence can completely simulate human brain intelligence
Modifying the SSH default port when installing Oracle RAC makes CRS unable to install
【学习笔记】线性基
B_ QuRT_ User_ Guide(29)
设置cmd的编码为utf-8