0%

rust字符串

1 字符串

参考: https://fasterthanli.me/articles/working-with-strings-in-rust

UTF8字符表和UTF8编码是两个东西, 字符表是一个,也叫 Unicode; 编码方式有很多种,UTF-8,UTF-16等等,目前通用的编码方式是UTF8, 这个是变长字节,1个unicode字符可以编码成1-4字节的长度.
而UTF-32每个字符都是4字节表示,这样可以跟字符表一一对应,缺点就是浪费空间。

rust的 String 都是 utf-8 编码的,影响就是跟c++的 char 不等价, 不能理所当然的取长度.

1.1 String

底层相当于用 Vec<u8> 存储,不能索引,取出来的长度是底层编码后的长度,比如你好打印出6字节:

1
2
let hello = "你好".to_string();
println!("len:{}", hello.len()); // len:6

注意: "" 也是有效的String

1.2 char

是个 u32 类型的,用于表示 unicode 字符,注意这个不是UTF8编码,而是字符表中的字符序号。

1.3 str 和 &str

str是rust内部的类型,一般用的是 &str 引用。

1.4 b”abc”

"abc"&str 类型, 引用的是utf8;
b"abc"&[u8] 类型, 引用的是u8数组, 这个保证都是ascii字符;

注意这两个不是同一个类型

总结一下

  • String: rust内部字符串类型,是个单纯的字符串,utf8编码
  • str, &str: 字符串切片, 是 String 的索引;
  • char: 可以表示unicode 字符序号,u32(4字节足够存储所有的unicode编码);
  • Vec: u8数组,字节流;
  • [u8;3]: 3字节的 u8 定长数组, 长度也是类型的一部分,因此 [u8;3][u8;4] 不是一个类型,不能传参;
  • &[u8]: 是定长数组的切片引用, 类似 &str;

2 字面值和转义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1. 用 \x 转义二进制
let a = "I'm writing \x52\x75\x73\x74!";

// 2. 用\u 转义unicode
let unicode_codepoint = "\u{211D}";

// 3. 可以换行
let long_string = "String literals
can span multiple lines.
The linebreak and indentation here ->\
<- can be escaped too!";

// 4. 不要转义,前边加个"r"
let raw_str = r"Escapes don't work here: \x3F \u{211D}";

// 5. 不要转义,字符串里有双引号", 前后加个"#"
let quotes = r#"And then I said: "There is no escape!""#;

// 6. 字符串里有n个连续的"#", 就可以在前后加 n+1 个"#",最多可以有65535个....
let longer_delimiter = r###"A string with "# in it. And even "##!"###;