One - One Code All

Blog Content

Rust 字符串

Rust   2017-04-15 08:55:11

Rust 中有多种表示字符串的数据类型,其中最常用的是 str 和 String 两种类型。

str 类型

Rust 中有一个表示字符串的原始(primitive)类型 str。str 是字符串切片(slice),每个字符串切片具有固定的大小并且是不可变的。通常不能直接访问 str ,因为切片属于动态大小类型(DST)。所以,只能通过引用(&str)间接访问字符串切片。关于这一点,会在以后的文章中介绍。在下面的内容将不加区分的使用 str 和 &str。

可以通过字符串字面量构造 &str 类型的对象:

let s = "Hello, world!";

在 Rust 中,字符串字面量的类型是 & 'static str,因为它是被直接储存在编译后的二进制文件中的。

还可以使用切片的语法,从一个&str 对象构造出另一个 &str 对象:

let ss = &s[..3];

也可以将切片转换成相应的指针类型:

let p = s as *const str;

String 类型

像大部分常见的编程语言一样,String 是一个分配在堆上的可增长的字符串类型,它的定义如下:

struct String { 
   vec: Vec<u8>
}

从源码可以看出,String 是对 Vec 的简单包装。

String 保存的总是有效的 UTF-8 编码的字节序列。

构造一个空字符串:

let s = String::new();

还可以通过字符串字面量构造 String 类型的对象:

let hello = String::from("Hello, world!");

String 和 &str 之间有着非常紧密的关系,后者可以用来表示前者的被借用(Borrowed)的副本。

str 和 String 类型的转换

前面已经看到,字符串字面量可以转换成 String。反过来,String 也可以转换成str。这是通过解引用操作实现的:

impl Deref for String { 
   fn deref(&self) -> &str {
       unsafe { str::from_utf8_unchecked(&self.vec) }
   }
}

利用解引用操作就可以将 String 转换成 str:

let s: String = String::from("Hello");
let ss: &str = &s;

String 还可以连接一个 str 字符串:

let s = String::from("Hello"); 
let b = ", world!";
let f = s + b; // f == "Hello, world!"

如果要连接两个 String 对象,不能简单地直接相加。必须先通过解引用将后一个对象转换为 &str 才能进行连接:

let s = String::from("Hello");
let b = String::from(", world!");
let f = s + &b; // f == "Hello, world!"

注意这里字符串连接之后,s的所有权发生了转移,而b的内容复制到了新的字符串中。

从 String 到 str 的转换是廉价的,反之,从 str 转为 String 需要分配新的内存。

一般来说,当定义函数的参数时, &str 会比 String 更加通用:因为此时既可以传递 &str 对象也可以传递 String 对象。




上一篇:Rust 组织管理,多模块
下一篇:Rust中的集合类型之vectors

The minute you think of giving up, think of the reason why you held on so long.