昨天学完了vector
今天该学String
了
这玩意儿应该算是我们用的最多的类型了,但是这玩意儿居然是一个集合collection
,是一堆UTF-8
字符char
的集合?
实际上并不是,rust
开发者将String
定义为一堆bytes
字节的集合。
rust
的核心代码里是没有String
的,只有字符串切片str
,基本上都是&str
,它是一些存储在某些地方的UTF-8
字符char
数据的引用。比如你声明的字符串字面量
而String
上面文章说过了,是标准库里的类型。和字符串切片不同的是,它可变、拥有所有权。
有一点需要强调的一点是,不管是str
还是String
,它们都是基于UTF-8
编码的。如果使用超出UTF-8
范围的符号就会有问题。
另外,说一下rust
中String
为啥是一个集合。它其实是一个wrapper
包裹着一个vector
,然后再加点限制、功能等。而这个vector
是一个u8
类型的vector
。
既然是包裹的vector
,那么自然可以用和vector
的new
关联函数。
相信大家都很熟悉了,我们直接看例子吧
new是String
的关联函数,返回一个String
实例。
我们也习惯这么写了,如果有初始数据的话基本都是用下面这种
但其实,我们也可以用字符串切片来实现,这是之前从来没用过的。
使用to_string
方法会返回一个字符串类型,并且拥有了所有权。
两个都可用,看你自己的习惯。
我们之前好像有用到过一个方法push_str
的方法,来看下例子
push_str
需要的参数类型是字符串切片。
或者我们可以用push
添加char
给这个字符串
但这两种方式未免会有些麻烦,如果可以和别的于艳一样使用+
直接加起来那该多好。
rust
确实有这种方式,但是做了一定的限制。来看下例子
两个字符串类型相加会直接报错,需要调整为下面这种
第二个参数相加的变量得是字符串切片,而第一个参数必须要是字符串类型(拥有所有权)。
为什么会这样呢?因为+
操作符实际上会被转换为类似add
的方法
可以看到第一个参数接受的是自己并且是拥有所有权,这也就意味着s1
在add
完之后就失效了。
第二个参数则是一个字符串切片,但是我们明明用的是一个&String
的参数。
这也就是我为什么要说是类似add
方法了,还是有差别的。
可以看到使用&str
也是可行的。
为什么可以这样呢。。。实际上是编译器帮我们把&String
强制转换成了&str
。
另外,如果有多个字符串相加,那用+
来写还是很麻烦,在js
中,可以直接使用 ` ${}将多个字符串拼接到一起。
rust
中虽然没这么方便,但是还是有差不多功能的,也就是format!
,看到这个!
大家应该都知道是一个macro
了。来看下例子
在js
中,我们可以用过下标直接获取字符串的元素,但是在rust
中这么做是不行的。
为什么不行呢?
我们来看下字符串内部表现[5]
前面说过了String
实际上是Vec
加了一层wrapper
,里面的元素都是UTF-8
编码的字符。
我们来看下两个例子
这个hello
字符串的len
长度是4
,Hola
每一个字符逗占一个byte
。
来看这下俄语的长度,数了下应该是12
,但实际上是24
,为什么呢?因为一个俄语符号占两个byte
,也就是双字节。
实际上中文也是双字节。
所以通过下标获取就会出问题,可能抓到的元素不是自己想要的。
为什么要用字节存储呢?我们再来看一个例子
“नमस्ते”这是一个印度语,看这个完全不知道有多长。。。。
而在电脑会把它们转换为
一个Vec
。
试想一下,如果不是这个类型,那么就会被切割成这样
而这里面其实有俩符号并不是符合要求的,只是无意义语气符号,然后就会变成
这样就错了。
所以rust
会把他们会转换成u8
类型,这样就能保留原始数据,到时候再转回来就不会有问题。
最后还有一个原因那就是时间复杂度,在rust
中通过下标获取元素的时间复杂度为O(1)。但是这并不适用于字符串,因为字符串需要从头开始一直走到下标位置,为什么要这么做呢?因为并不确定有多少符号是正确有效的。
slicing Strings
)如果你真有这个需求,那就用切片的方式,不过在这之前,你得知道你截取的是啥语言,比如
前面说了,俄语符号占两个字节,所以这里截取的应该是Зд
如果你截取双字节符号是只截取了一半也就是一个字节,rust
会直接崩溃
由于符号字节占位不同,所以我们并不能直接遍历,来看下例子
chars
会返回字符串的符号迭代器
这样打印出来的符号就是正常的。
当然,如果你想获取字节,你也可以直接用bytes
方法
相信看到这里,你也觉得rust
里的字符串好麻烦,好复杂。。。但是这也是rust
解决问题的一种方式吧,谁又能想到把字符串类型当做一个集合呢?
最后,如果觉得对你有帮助的话,请务必点个赞,谢谢~
发布于 2022-12-10 18:37・IP 属地广东