Go xmas2020 学习笔记 04、Strings
课程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com)
主讲老师 Matt Holiday
04-Strings
Strings
字符串在 go 中都是 unicode ,unicode 是一种特殊的技术用于表示国际通用字符。
rune 相当于 wide character,是 int32 的同义词,四个字节足够大,任何 unicode、字符,逻辑字符 可以指向它。
但是为了让程序更高效,我们不想一直用 4 个字节表示每个字符,因为很多程序使用 ascii 字符。
因此有一种称为 utf-8 编码的 unicode 技术,以字节 byte 表示 unicode 的简便方法。
从物理角度上看,strings 就是 unicode 字符的 utf-8 编码。
ascii characters 适合 0-127 的范围
func main() {
s := "élite"
fmt.Printf("%8T %[1]v %d\n", s, len(s))
fmt.Printf("%8T %[1]v\n", []rune(s))
b := []byte(s)
fmt.Printf("%8T %[1]v %d\n", b, len(b))
}
string élite 6
[]int32 [233 108 105 116 101]
[]uint8 [195 169 108 105 116 101] 6
é 为 233 超出了 ascii 的表示范围,由 2 个字节表示,而不是为每个字符使用 4 个字节,这是 utf8 编码的效果。中文字经常为 20000 的数字,五个中文字会用 15 个字节表示。
len(s) 显示 6 的原因,在程序中字符串的长度是在 utf-8 中编码字符串所必需的字节字符串的长度
The length of a string in the program is the length of the byte string that's necessary to encode the string in utf-8,not the number of unicode characters
就是说给定一个字符串,把它进行 utf-8 编码需要的字节数量就是它的长度,而不是 unicode 字符的数量。
String structure
可以把图片左边的 s 理解为一个描述符(描述符不是指针、不是 go 的专业术语),它有指针和额外的信息(字节数)。
go 字符串末尾没有空字节,很多编程语言通过循环字符串判断空字节获取长度,效率并不高。在 go 中字符串长度直接保存在描述符中。
通过索引字符串创建 hello 的时候,hello 的 data 指向的是跟 s 描述符 data 的相同内存地址(共享存储)。
因为字符串没有空字节,而且它们是不可变的,所以共享存储是完全可行的。world 也是同理。它们重用 s 中的内存。
t := s
的结果是 t 将有与 s 一样的内容,但是 t 跟 s 是不一样的描述符。
b、c 与 s 共享存储。
d 开辟了新的内存空间,存入了新的字符串。
s[5] = 'a' 出错,字符串是不可变的,不能单独修改字符串。
s +="es" 相当于 s = s + "es" ,开辟了新的内存空间,复制原有内容,再添加新内容,并使 data 指向新的内存地址。
原来的字符串并没有改变、消失,因为 b、c 依旧指向原来的内存地址,s 指向了新开辟的内存地址。
String functions
s = strings.ToUpper(s)
字符串不允许被更改,所以会创建新字符串进行旧字符串的拷贝并大写。由于开辟了新的内存空间,将返回值给 s 也就很好理解了。
如果没有变量引用字符串,它会自动被垃圾回收。
Practice
做一个替换句子中指定单词的程序
main.go
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
if len(os.Args) < 3 {
fmt.Fprintln(os.Stderr, "not enough args")
os.Exit(-1)
}
old, new := os.Args[1], os.Args[2]
scan := bufio.NewScanner(os.Stdin)
for scan.Scan() {
s := strings.Split(scan.Text(), old)
t := strings.Join(s, new)
fmt.Println(t)
}
}
os.Args
运行 go 程序时附加的参数,具体可以看前几节的内容。
buffio.NewScanner(os.Stdin)
扫描仪是一个缓冲io工具,默认以行分割输入的内容。举个例子,如果输入特别大,就可以把它以一系列行的形式读取。
scan.Scan()
将循环读取行,如果有可用的行读取将会返回true。
scan.Text()
获取读取的行。
for 循环中使用 strings
标准库的 Split
方法根据旧单词 变量 old
(大小写敏感)分割字符串获得字符串切片。
再将切片传入 strings
标准库的 Join
方法,通过新单词 变量 new
合并字符串。
test.txt
matt went to greece
where did matt go
alan went to rome
matt didn't go there
第一行留空行,因为会读取 BOM 头,具体请看这篇文章
重定向管道流读取TXT文本第一次读取为""空字符串 - 小能日记 - 博客园 (cnblogs.com)
result
cat test.txt | go run . matt ed
ed went to greece
where did ed go
alan went to rome
ed didn't go there
这里我们使用了重定向管道,读取 test.txt 的内容当做 main.go 的程序输入,指令在 linux 是 go run . matt ed < test.txt。
old, new := os.Args[1], os.Args[2]
old, new = new, old
值得注意的一点是初始化变量的方式,使用一行初始化两个变量。巧妙的是可以用这种方式进行两个变量值的交换。
Go xmas2020 学习笔记 04、Strings的更多相关文章
- 机器学习实战(Machine Learning in Action)学习笔记————04.朴素贝叶斯分类(bayes)
机器学习实战(Machine Learning in Action)学习笔记————04.朴素贝叶斯分类(bayes) 关键字:朴素贝叶斯.python.源码解析作者:米仓山下时间:2018-10-2 ...
- SaToken学习笔记-04
SaToken学习笔记-04 如果有问题,请点击:传送门 角色认证 在sa-token中,角色和权限可以独立验证 // 当前账号是否含有指定角色标识, 返回true或false StpUtil.has ...
- Redis:学习笔记-04
Redis:学习笔记-04 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 10. Redis主从复制 1 ...
- xml基础学习笔记04
今天继续xml学习,主要是:SimpleXML快速解析文档.xml与数组相互转换 .博客中只是简单的做一个学习记录.积累.更加详细的使用方法,可以查看php手册 1.SimpleXML快速解析文档 前 ...
- OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- [Golang学习笔记] 04 程序实体1 变量声明
变量声明: Go语言的程序实体包含:变量.常量.函数.结构体和接口,是一门静态类型的编程语言. (在声明变量或常量的时候,需要指定类型,或者给予足够信息是的Go语言能够推导出类型) Go语言变量的类型 ...
- [原创]java WEB学习笔记04:Servlet 简介及第一个Servlet程序(配置注册servlet,生命周期)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Bash脚本编程学习笔记04:测试命令test、状态返回值、位置参数和特殊变量
我自己接触Linux主要是大学学习的Turbolinux --> 根据<鸟哥的Linux私房菜:基础篇>(第三版) --> 马哥的就业班课程.给我的感觉是这些课程对于bash的 ...
- Qt Creator 源码学习笔记04,多插件实现原理分析
阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...
随机推荐
- Android 12(S) 图形显示系统 - BufferQueue的工作流程(十一)
题外话 我竟然已经写了这个系列的十一篇文章了,虽然内容很浅显,虽然内容很枯燥,虽然内容也许没营养,但我为自己的坚持点赞! 一.前言 前面的两篇文章,分别讲解了Producer的处理逻辑和queue b ...
- web自动化之定位
UI自动化必不可少的操作--元素定位 8大基础定位 driver.find_element_by_id() # id定位 driver.find_element_by_name() # name定位 ...
- C# 委托应用总结(委托,Delegate,Action,Func,predicate)
C# 委托应用总结 一.什么是委托 1.1官方解释 委托是一种定义方法签名的类型.当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联.您可以通过委托实例调用方法. 1.2个人理解 委托就是执 ...
- 【模板】动态 DP
luogu传送门. 最近学了一下动态dp,感觉没有想象的难. 动态DP simple的DP是这样的: 给棵树,每个点给个权值,求一下最大权独立集. 动态DP是这样的: 给棵树,每个点给个权值还到处改, ...
- 知识点简单总结——BSGS与EXBSGS
知识点简单总结--BSGS与EXBSGS BSGS 给出 $ A,B,C,(A,C)=1 $ ,要你求最小的 $ x $ ,使得 $ A^x \equiv B(mod \ C) $ . 在数论题中经常 ...
- 洛谷P1049 [NOIP2001 普及组] 装箱问题
本题就是一个简单的01背包问题 1.因为每个物品只能选一次,而且要使箱子的剩余空间为最小.所以可以确定属性为 MAX 2.由于是从n个物品里面选i个物品 那么就是选出的i个物品的空间总和要尽可能的 ...
- idea 下 Vue
一.需要了解的基本知识 node.js Node.js是一个Javascript运行环境(runtime),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.N ...
- 什么是Java序列化,如何实现Java序列化?或者请解释Serializable接口的作用?
象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另 ...
- Dubbo Monitor 实现原理?
Consumer 端在发起调用之前会先走 filter 链:provider 端在接收到请求时也是 先走 filter 链,然后才进行真正的业务逻辑处理. 默认情况下,在 consumer 和 pro ...
- Container 在微服务中的用途是什么?
容器是管理基于微服务的应用程序以便单独开发和部署它们的好方法.您可以将 微服务封装在容器映像及其依赖项中,然后可以使用它来滚动按需实例的微服务, 而无需任何额外的工作.