6.9 KiB
字符串拼接
+运算符和format!宏连接
+ 运算符使用以下add方法
fn add(self, s: &str) -> String {
在调用add时使用&s2是因为编译器可以将**&String参数强制转换为&str**。当我们调用add方法时,Rust使用deref强制转换。
使用+操作符会失去第一个参数的所有权,同时在处理多个字符串拼接时会特别笨拙。以下为使用format!宏进行拼接,不会失去所有权(使用引用)。
字符串索引
Rust 字符串不支持索引、
内部表示
一个字符串是 Vec的封装。当以 UTF-8 编码时,这些字母中的每一个都占用 1 个字节。但当以 Unicode 编码时,每一项占用两个字节。字符串字节的索引并不总是与有效的 Unicode 标量值相关联。 UTF-8 是一种将 Unicode 编码转换成字节序列的转换格式。
因为存储的单元字节大小不同,故而直接通过下标取值有时会取到错误值。为了避免返回意外值并导致可能无法立即发现的错误,Rust 根本不编译此代码,并在开发过程的早期防止误解。
字节和标量值和字形群
关于 UTF-8 的另一点是,从 Rust 的角度来看,实际上有三种相关的方式来查看字符串:作为字节、标量值和字素簇(最接近我们所说的字母)。
印地语单词“नमस्ते”,它存储为一个u8
值向量,如下所示:
[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164,
224, 165, 135]
18个字节,这就是计算机最终存储此数据的方式。如果我们将它们视为 Unicode 标量值,这就是 Rust 的char
类型,那么这些字节如下所示:
['न', 'म', 'स', '्', 'त', 'े']
这里有六个char
值,但第四个和第六个不是字母:它们是本身没有意义的变音符号。最后,如果我们将它们视为字素簇,我们会得到人们所说的构成印地语单词的四个字母:
["न", "म", "स्", "ते"]
Rust 提供了不同的方式来解释计算机存储的原始字符串数据,这样每个程序都可以选择它需要的解释,而不管数据使用的是哪种人类语言。
Rust 不允许我们通过索引 aString
来获取字符的最后一个原因是索引操作预计总是需要常数时间 (O(1))。但是不能保证 a 的性能String
,因为 Rust 必须遍历从头到索引的内容以确定有多少个有效字符。
字符串切片
可以使用索引创建字符串切片,但需谨慎,会产生意外panic。
当对二个字节字符取一个字节时,会产生如下错误:
迭代字符串
chars
方法返回每个字符,bytes
方法返回每个原始字节。
有效的 Unicode 标量值可能由超过 1 个字节组成。
HashMap<K,V>
创建HashMap
首先从标准库引用HashMap。哈希映射将其数据存储在堆上。哈希映射是同类型的: 所有键必须具有相同的类型,所有值也必须具有相同的类型。
访问HashMap
get方法返回一个Option<&V>。如果哈希映射中该键没有值,get
将返回None
。
unwrap_or()
函数是 Rust 中 Option
类型的一个常用函数,它用于在值为 None
时返回一个默认值。它接受一个参数,在 Option
类型为 None
时返回该参数。
遍历HashMap
以任意顺序打印每一对。
HashMap所有权
对于实现Copy
特征的类型,如i32
,值被复制到哈希映射中。对于拥有的值,如String
,这些值将被移动,哈希映射将成为这些值的所有者。
存储字符串引用(保留所有权)
但是可能会出现这种情况:
推荐使用clone:
更新HashMap的值
- 覆盖,插入了两个相同key
- 仅在键不存在时添加键和值。
如果该键确实存在于哈希映射中,则现有值应保持原样。如果键不存在,则插入它并为其赋值。entry
将您要检查的密钥作为参数。该entry
方法的返回值是一个枚举Entry
,代表一个可能存在也可能不存在的值。
or_insert
方法被定义为如果该键存在,则Entry
返回对相应Entry
键值的可变引用,如果不存在,则将参数作为该键的新值插入,并返回对新值的可变引用。
- 基于旧值更新值
split_whitespace方法返回 中值的子片的迭代器,由空格分隔text。该or_insert
方法返回一个可变引用 ( &mut V
) 到指定键的值。这里我们将可变引用存储在count
变量中,因此为了分配给该值,我们必须首先count
使用星号 (*
) 取消引用。
哈希函数
默认情况下,HashMap使用一种名为SipHash的哈希函数,可以提供对哈希表的拒绝服务(DoS)攻击的抵抗力。这不是最快的哈希算法,但是为了更好的安全性而降低性能的权衡是值得的。如果您对代码进行了分析并发现默认哈希函数对您的目的太慢,您可以通过指定其他函数来切换。哈希器是一种实现BuildHasher特征的类型。