031-神奇的字符串
无论在哪种语言里,字符串都是一种相当重要的数据类型。很多语言都有字符串的概念,但是又有很大区别。比如 c 语言里,需要使用一个以 '\0'
结尾的字节数组来表示字符串;c++ 里使用 std::string
类型表示字符串;在 java 里是 String
. 在这些语言里,字符串并不是一种基础数据类型,而是更加复杂的复合类型,或者『类』类型。
接下来即将讨论的 go 语言里的字符串,它就是一种基础数据类型,和上面那些语言有着相当大的区别。
1. 不可变的字符串
go 里的字符串,是不可变的字节序列(immutable sequence of bytes). 这句话有两层含义:
- 不可变 (immutable)
- 字节序列(sequence of bytes)
第二点在后面的第 2 节里说明。这里先看第一点。
在 go 语言里,字符串是基本类型,这一点和 python/nodejs 语言非常像。具体一点,我们说字符串是一个不可分割,不可修改的整体。举 2 个反例:
- c 语言
char s[] = "abcde";
s[0] = 'f';
- c++ 语言
std::string s = "abcde";
s[0] = 'f';
在上面的例子中,对字符串进行修改是合法的。然而,这种修改似乎破坏了字符串的整体性。一个字符串,它就像一个完整的人,它的局部不应该被随随便便更改才对。
在 go 语言里,下面的操作是不合法的:
var s string = "abcde"
s[0] = 'f'; // not ok
可能你会着急问,如果要修改怎么办?这个问题解决起来很简单,创建一个新的字符串就行了。在 go 里你可以这么处理:
var s string = "abcde"
var t string = "f" + s[1:] // 创建一个新字符串
2. 遍历字符
刚刚我们看到了,要想访问字符串的『字符』我们使用下标就可以做到。但是还有一点点小问题,稍后再说,先来看一个例子:
var s string = "abcde"// len 函数是 go 的内置函数,可以计算字符串的长度。在第一章节我们也用过,还记得吗?
for i := 0; i < len(s); i++ {fmt.Printf("%c\n", s[i])
}
最后会输出:
a
b
c
d
e
下面来看第二个例子:
var s string = "你好,世界"// len 函数是 go 的内置函数,可以计算字符串的长度。在第一章节我们也用过,还记得吗?
for i := 0; i < len(s); i++ {fmt.Printf("%c\n", s[i])
}
运行后输出:
图1 输出字符???
首先这个输出是什么鬼?难道不认识中文吗?还是中文太博大精深了?这里有两点需要注意:
- 字符串的下标一次只索引一个字节数据
- 字节 != 字符
在 ascii 码里,字节和字符是一致的,但是到了汉字世界,就不成立了。
先解释一下乱码的原因:在 go 里,源文件使用 utf-8 进行编码。也就是说你写在源文件里的 “你好,世界” 也是 utf-8 编码的。程序运行后,在 go 语言的内存里,这个字节序列保存的也是 utf-8 字节序列(注意这里我提到了字节序列)。而 go 的下标一次只索引一个字节的数据,因此你每次索引的只是 utf-8 字节序列的某一个部分,看到的当然是个乱码。
如何正确遍历字符这个问题放到后面的博客里解决,这里先暂放一放。继续下一个话题。
3. 字符串切片
说到字符串切片,大多数人就想到了 python. 没错,go 里的切片也很强大,强的接近 python……好吧,go 的字符串切片已经相当不错了,至少比 c++ 语言字符串要强大 10000 万倍了是不。
可能有同学还不知道切片是什么意思,其实它就是取子串,即得指定范围的 substring. 举例:
var s string = "Hello, world"a := s[2:] // "llo, world"
b := s[:5] // "Hello"
c := s[2:5] // "llo"
go 的切片没有 Python 强,是因为 Python 还支持使用负数做索引(有点逆天是不)。不过我们的 go 是静态语言,能做到这样,也已经很牛逼了!
接下来,我们再回顾一下『不可变』的含义,它背后隐藏的目的是什么?
- 可变性带来的缺点
不妨假设字符串 s 是可变的,我们执行 s[2] = 'x'
,会不会导致字符串 a
变成 "xlo world"
? 很明显,我们不希望这件事情发生,因为字符串 s 和 a 本来就是不相干的。
如此一来,为了防止字符串 a 和 s 产生关联,我们又需要为 a 重新开辟一块内存空间,将 s[2:]
的内容复制到新的空间去。
- 不可变的优势
好了,『可变』的字符串为切片操作带来了困扰。那如果是『不可变』的呢?这意味着字符串 a 可以继续使用 s 的内存,而不必再开辟新空间!因为字符串 s 本来就是不可变的,所以共享它的内存是安全的。
图2 『不可变』字符串的好处是可以共享内存
这个特性会让字符串的复制和切片操作变得非常低廉,因为它没有任何开辟新内存和拷贝字节的代价!
4. 总结
- 掌握字符串类型
031-神奇的字符串相关推荐
- 【PHP】`异客塞尔`世界 与 神奇的字符串++
目录 [PHP]`异客塞尔`世界 与 神奇的字符串++ 通往`异客塞尔`世界 独特编号破坏了异世界的`优雅` 神奇的`++`带来了和平 初寻的`++`的真相 [PHP]异客塞尔世界 与 神奇的字符串+ ...
- 神奇的字符串-包含26个字母
PG 如果一个字符串包含了所有的字符(a到z,不区分大小写),那么我们就说这是一个神奇的字符串. 现在,给你一个由大写和小写字母组成的字符串,判断其是否为神奇的字符串. Input 第一行包含一个整数 ...
- 【Python】Python中神奇的字符串驻留机制
今天有一个初学者在学习Python的时候又整不会了. 原因是以下代码: a = [1, 2, 3] b = [1, 2, 3] if a is b: print("a and b point ...
- 【每日一题】031 神奇的6位数
题目详情: 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可. 有一个 6位的正整数,它有个很神奇的性质: 分别用2,3,4,5,6 去乘它,得到的仍然是 6 位数,并且乘积中所 ...
- 1.神奇的字符串之快速求和
文章目录 前言 正题 先看第一个代码 直接循环取出每一位数 总结 . 前言 这个专栏是分享一些好用的数据 和一些解题比较快的小方法 会持续更新 因为博主还是计算机方向的小白 知道的东西还是很少 希望大 ...
- 4417. 神奇的字符串
Solution: 我们要求出以j点为开头的长度为m的子串有多少位和s不同,等价于求c[j]与s[0]不同,c[j + 1]与s[1]不同,c[j + 2] 与s[2] 不同....... c[j + ...
- LeetCode 481. 神奇字符串(找规律)
1. 题目 神奇的字符串 S 只包含 '1' 和 '2',并遵守以下规则: 字符串 S 是神奇的,因为串联字符 '1' 和 '2' 的连续出现次数会生成字符串 S 本身. 字符串 S 的前几个元素如下 ...
- Java实现 LeetCode 481 神奇字符串
481. 神奇字符串 神奇的字符串 S 只包含 '1' 和 '2',并遵守以下规则: 字符串 S 是神奇的,因为串联字符 '1' 和 '2' 的连续出现次数会生成字符串 S 本身. 字符串 S 的前几 ...
- alxc tool 报错数组超出了界限_代码审计之报错信息泄露与字符串截断
机器在语言编码转换的时候,经常会出现各种各样的异常,这些神奇的字符串就有可能组合成一堆乱码出来,也有可能直接把程序搞崩溃掉,不过总有那么一些字符,可以帮助我们在利用漏洞的时候变得更简单一些,下面我们就 ...
- php数据类型之字符串
字符串就是所有我们可见和不可见的字符,就是我们日常当中说的话,就是我想说:"小明好帅"或者"凤姐,我爱你!".字符串,就是我想表达的一切让人看到的字符. 例如可 ...
最新文章
- java获取下一季末_java取当前周期、月初至月末、季度初至季度末日期。
- Port already be taken
- matlab画平行坐标轴的直线
- 第十二周项目1-阅读程序(三)
- VSCode中屏蔽文件files.exclude和屏蔽文件搜索search.exclude
- 多样化实现Windows Phone 7本地数据访问3——DB4O
- 如何用ABAP代码读取SAP Business partner的附件数据
- javaone_JavaOne 2012 – 2400小时! 一些建议
- python selenium po_python+selenium基于po模式的web自动化测试框架
- mysql2005错误码_SQL Server2005 常见错误及解决方案
- ubuntu 12.04 安装intel i5-6500 的集成网卡驱动【自身经历,验证OK】
- java socket监听_Java -socket接口(监听)
- Latex绘制三线表
- 故宫,中国古代建筑艺术的奇葩
- 【开发工具】MySQL免安装版
- Foxmail 设置自动落款签名
- 极米Z6X Pro值得购买吗?这篇评测告诉你
- .obj 和 .mtl文件格式
- 在Linux下测试SD卡的读写速度
- Java开源的11个中文分词器使用方法和分词效果对比