You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.9 KiB

字符串拼接

+运算符和format!宏连接

+ 运算符使用以下add方法

fn add(self, s: &str) -> String {

在调用add时使用&s2是因为编译器可以将**&String参数强制转换为&str**。当我们调用add方法时,Rust使用deref强制转换。

image-20230116161123068

使用+操作符会失去第一个参数的所有权,同时在处理多个字符串拼接时会特别笨拙。以下为使用format!宏进行拼接,不会失去所有权(使用引用)。

image-20230116162822236

字符串索引

Rust 字符串不支持索引、

image-20230116163655653

内部表示

一个字符串是 Vec的封装。当以 UTF-8 编码时,这些字母中的每一个都占用 1 个字节。但当以 Unicode 编码时,每一项占用两个字节。字符串字节的索引并不总是与有效的 Unicode 标量值相关联。 UTF-8 是一种将 Unicode 编码转换成字节序列的转换格式。

image-20230116165523344

因为存储的单元字节大小不同,故而直接通过下标取值有时会取到错误值。为了避免返回意外值并导致可能无法立即发现的错误,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。

image-20230129100107046

当对二个字节字符取一个字节时,会产生如下错误:

image-20230129100347688

迭代字符串

chars方法返回每个字符,bytes方法返回每个原始字节。

有效的 Unicode 标量值可能由超过 1 个字节组成。

image-20230129103709654

HashMap<K,V>

创建HashMap

首先从标准库引用HashMap。哈希映射将其数据存储在堆上。哈希映射是同类型的: 所有键必须具有相同的类型,所有值也必须具有相同的类型。

image-20230129105734858

访问HashMap

get方法返回一个Option<&V>。如果哈希映射中该键没有值,get将返回None

unwrap_or() 函数是 Rust 中 Option 类型的一个常用函数,它用于在值为 None 时返回一个默认值。它接受一个参数,在 Option 类型为 None 时返回该参数。

image-20230129111116825

遍历HashMap

以任意顺序打印每一对。

image-20230129112257955

HashMap所有权

对于实现Copy特征的类型,如i32,值被复制到哈希映射中。对于拥有的值,如String,这些值将被移动,哈希映射将成为这些值的所有者。

image-20230129113639017

存储字符串引用(保留所有权)

image-20230129114217635

但是可能会出现这种情况:

image-20230129115000375

推荐使用clone:

image-20230129115130528

更新HashMap的值

  1. 覆盖,插入了两个相同key

image-20230129132045261

  1. 仅在键不存在时添加键和值

如果该键确实存在于哈希映射中,则现有值应保持原样。如果键不存在,则插入它并为其赋值。entry将您要检查的密钥作为参数。该entry方法的返回值是一个枚举Entry,代表一个可能存在也可能不存在的值。

or_insert 方法被定义为如果该键存在,则Entry返回对相应Entry键值的可变引用,如果不存在,则将参数作为该键的新值插入,并返回对新值的可变引用。

image-20230129132647150

  1. 基于旧值更新值

split_whitespace方法返回 中值的子片的迭代器,由空格分隔text。该or_insert方法返回一个可变引用 ( &mut V) 到指定键的值。这里我们将可变引用存储在count变量中,因此为了分配给该值,我们必须首先count使用星号 (*) 取消引用。

image-20230129134200025

哈希函数

默认情况下,HashMap使用一种名为SipHash的哈希函数,可以提供对哈希表的拒绝服务(DoS)攻击的抵抗力。这不是最快的哈希算法,但是为了更好的安全性而降低性能的权衡是值得的。如果您对代码进行了分析并发现默认哈希函数对您的目的太慢,您可以通过指定其他函数来切换。哈希器是一种实现BuildHasher特征的类型。