Go xmas2020 学习笔记 05、Arrays, Slices, and Maps
课程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com)
主讲老师 Matt Holiday

05-Arrays, Slices, and Maps
In memory

string、array、slice 在内存中是连续存储的,map不是连续存储的。
Array

在创建数组的时候需要指定大小,如果不指定需要使用 ... ,图中 a、b 将是固定的 24 字节对象(int在64位操作系统上默认为int64),一旦设定不能改变。
d=b 中,由于数组只是一块内存,并不是像字符串那样的描述符,我们只是物理地复制了字节。当数组大小不一致时,无法进行拷贝复制。
Slice

切片有描述符,指向一个特定的内存地址。它的工作方式类似于字符串的工作方式。
切片描述符包含 data、len、capacity。
append 方法需要把返回值重新赋给 a,假设 a 指向的内存区域已经满了,再添加元素就要开辟新的更大的内存区域存放。
a=b 表示 b 描述符的内容被拷贝到 a 描述符中。
e:=a 新建一个描述符,内容与 a 描述符内的一致。
切片可以被切片(截取)操作,就像从字符串(前面的os.Args[1:])中取出切片,从切片数组切片等。
package main
import "fmt"
func main() {
t := []byte("string")
fmt.Println(len(t), t)
fmt.Println(t[2])
fmt.Println(t[:2])
fmt.Println(t[2:])
fmt.Println(t[3:5], len(t[3:5]))
}
6 [115 116 114 105 110 103]
114
[115 116]
[114 105 110 103]
[105 110] 2
fence post error

栅栏柱错误:假设我有三个栅栏部分,我必须有四个栅栏在他们旁边将它们固定住。(不懂直接看图)
Compare Array、Slice

切片可以是任意长度,而且大部分 Go 的标准库使用切片作为参数。
切片是不能进行比较的,想进行比较可以使用数组。这也导致切片不能作为 Map Key。
数组可以作为一些算法必备的数组。大小固定,值不改变。近似于伪常量。注意,不能添加 const 常量关键字,只有数字,字符串,布尔值可以作为常量。

Example

a[0]=4 因为 a 只是 w 的值拷贝(数组),所以修改后 w 并没有被修改。
b[0]=3 将会使 x 修改,因为两者 data 都指向同一个内存地址。(但是要注意,这是值拷贝,如果添加元素过多,会导致 b 的 data 指针使用新的内存地址而 x 还是指向原来的)
copy(c, b) 函数不会因为切片大小不同出错,会尽可能把 b 切片中的元素拷贝到 c 中。
我们可以对数组切片如 z := a[0:2] z 将是一个切片,指向 a 的前两个元素,go 会自动提供数组来保存。
Map

假设要计算一个文件中不同单词出现的次数,就可以使用 Maps。是一个 Hash table。
m 是一个描述符,但是整体为空。 p 的 data 指针指向一个哈希表。

map 与 map 间不能进行比较,只能进行 nil 比较。
可以查看 map 的长度,不能查看 map 的容量。

可以通过获取第二个参数判断键值对是否存在。
Built in functions

Make nil useful

由于 len、cap、range 这些内建函数是安全的,我们不需要 if 判断 nil 就可以直接使用。
range 将会跳过 nil、empty 的循环对象。
Quote

一种不影响你思考编程的方式的语言是不值得了解的
Practice
编写一个段落单词计数器,输出前三个出现次数最多的单词。
main.go
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
func main() {
scan := bufio.NewScanner(os.Stdin)
words := make(map[string]int)
// ^ 默认是按行读取,所以手动指定按单词读取
scan.Split(bufio.ScanWords)
for scan.Scan() {
words[scan.Text()]++
}
fmt.Println(len(words), "unique words")
type kv struct {
key string
val int
}
var ss []kv
for k, v := range words {
ss = append(ss, kv{k, v})
}
// ^ 直接修改原切片
sort.Slice(ss, func(i, j int) bool {
return ss[i].val > ss[j].val
})
for _, s := range ss[:3] {
fmt.Println(s.key, "appears", s.val, "times")
}
}
scan.Split(bufio.ScanWords) Scanner 默认是按行读取,所以手动指定按单词读取。
kv{k, v} 结构体的初始化
sort.Slice 函数直接修改原切片,传入的函数在 return 前面的元素排在切片的前面。如左>右,则大的元素在切片最前面,属于降序排序。
test.txt
matt went to greece
where did matt go
alan went to rome
matt didn't go there
第一行是空行是有原因的,这是 BOM头(Byte Order Mark) 导致的,具体请看另一篇文章
重定向管道流读取TXT文本第一次读取为""空字符串 - 小能日记 - 博客园 (cnblogs.com)
result
cat test.txt | go run .
12 unique words
matt appears 3 times
to appears 2 times
go appears 2 times
Go xmas2020 学习笔记 05、Arrays, Slices, and Maps的更多相关文章
- Go xmas2020 学习笔记 10、Slices in Detail
10-Slices in Detail. Slice. Empty vs nil slice
- go学习笔记-Data类型(Arrays, Slices and Maps)
Data类型(Arrays, Slices and Maps) array array就是数组,定义方式如下: var arr [n]type 在[n]type中,n表示数组的长度,type表示存储元 ...
- 机器学习实战(Machine Learning in Action)学习笔记————05.Logistic回归
机器学习实战(Machine Learning in Action)学习笔记————05.Logistic回归 关键字:Logistic回归.python.源码解析.测试作者:米仓山下时间:2018- ...
- C++ GUI Qt4学习笔记05
C++ GUI Qt4学习笔记05 qtc++正则表达式 QIntValidator -- 只让用户输入整数 QDoubleValidator -- 只让用户输入浮 ...
- [Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明
作用域访问权限: 程序实体访问权限(作用域)有三种:1. 包级私有(代码包)2. 模块级私有(代码包)3. 公开(全域). 一个函数是一个代码块.一个程序实体的作用域总是会被限制在某个代码块中.好处: ...
- stm32寄存器版学习笔记05 PWM
STM32除TIM6和TIM7外都可以产生PWM输出.高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出. 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟 ...
- [原创]java WEB学习笔记05:Servlet中的ServletConfig对象
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Bash脚本编程学习笔记05:用户交互与脚本调试
用户交互 在<学习笔记04>中我们有提到位置参数,位置参数是用来向脚本传递参数的一种方式.还有一种方式,是read命令. [root@c7-server ~]# read name alo ...
- xml基础学习笔记05
Xpath快速解析 如题一样,本篇主要说说Xpath快速查找XML文档 * Xpatn.Xquery,是专门用来查询xml的语言 * 查询xml非常快 Xpatn.Xquery,是专门用来 ...
随机推荐
- 【面经】MyBatis常见面试问题
1.什么是 MyBatis? 答:MyBatis 是一个可以自定义 SQL.存储过程和高级映射的持久层框架. 2.讲下 MyBatis 的缓存 答:MyBatis 的缓存分为一级缓存和二级缓存,一级缓 ...
- kafka 第一次小整理(草稿篇)————分发的基本思路[三]
前言 简单整理一下分发的基本思路. 正文 kafka 原本是做日志管理系统,主要是分发这块的. 那么如何做分发呢? 分发的是什么呢? 分发的其实是日志,日志是事件状态,kafka 内部就叫做Recor ...
- Linux TC 流量控制介绍
前段时间在做一些测试的时候接触到了Linux tc,因为需要对数据包添加延迟,用到了tc中的netem.添加简单的延迟非常简单,像这样一条命令就搞定了:$ tc qdisc add dev eth0 ...
- C 上楼梯 中国石油大学新生训练赛#11
问题 C: 上楼梯 时间限制: 1 Sec 内存限制: 128 MB提交 状态 题目描述 明明上n 级台阶可用四种步幅, 当然每种步幅花费的体力也不一样, 对应关系如下明明开始有m 个体力, 求他最 ...
- 整理分布式锁:业务场景&分布式锁家族&实现原理
1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...
- 数据库连接Database link?
在一个用户下,可以获取到另外的用户下的表的数据,通常在跨数据库时使用. create database link link93 connect to scott identified by tiger ...
- 什么是原子操作?在 Java Concurrency API 中有哪些原 子类(atomic classes)?
原子操作(atomic operation)意为"不可被中断的一个或一系列操作" . 处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作. 在 Java 中可以通 ...
- 深入理解Java虚拟机-HotSpot虚拟机对象探秘
一.对象的创建过程 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那就先执行相应的类 ...
- SPI简单解析
什么是SPI 一种服务加载方式,全名为Service Provider Interface,Service提供者接口 如果我们要抽象里面的模块,在面对对象编程当中,我们模块之间,一般推荐模块之间基于 ...
- 什么是 Spring 引导的执行器?
Spring Boot 执行程序提供了 restful Web 服务,以访问生产环境中运行应用程序 的当前状态.在执行器的帮助下,您可以检查各种指标并监控您的应用程序.