Rust中的&str和String有什么区别

&str和String让Rust初学者困惑不已。这里简单的介绍一个&str和String的区别。

String就像是Vec一样是动态分配在堆heap上的字符串类型,它指向一串UTF8编码的字节序。当需要拥有该字符串,要更改字符串的内容,要把字符串在线程之间传递,要在运行时动态创建字符串时使用此类型。

str也指向一串UTF8编码的字节序,但并不拥有指向的字符串,而仅仅只是一个“string slice”。slice的详细解释点链接。str绝大多数情况下以引用&str的形式出现。又被称为字符串字面值(string literal)。
和String指向的字符串肯定分配在堆上面不一样,str指向的字符串可能出现在各种地方:
1. 在程序的全局静态空间(.text段??)。一个string literal的类型和生命期是:&’static str。字符串的数据硬编码进生成的程序或库文件,但程序加运行时,字符串加载进内存。
2. 分配在堆上面 String有一个方法是as_str,它返回一个&str,指向String管理的堆上面的字符串。另外,String有实现Deref<Target=str>这样一个Trait,让所有接受&str作为参数的函数,都可以传String的引用。编译器会自动把&String转成&str。
3. 分配在栈上面 如下面的代码,变量stack_str的类型是&str,它指向栈上面的字符串。

use std::str;

let x: &[u8] = &[b'a', b'b', b'c'];
let stack_str: &str = str::from_utf8(x).unwrap();

如果以C++程序员的视角看String和&str。一个Rust的String类似std::string,完全拥有并管理(创建,销毁)需要的内存。而Rust的&str则类似char*(当然实际上要复杂很多),仅仅指向字符串,不负责管理对应的内存。

再看看String和&str的互转化:
&str转String可以用三种方法

    let a: String = "hello rust".into();
    let c: String = "hello rust".to_string();
    let b: String = String::from("hello rust");
    println!("{}", a);   // 都输出 hello rust
    println!("{}", b);
    println!("{}", c);

String转&str可以直接引用String类型的值或者调用String的as_str方法。

let a: String = String::from("hello rust");
let aaa: &str = &a;
let bbb: &str = a.as_str();

转载请注明出处链接 http://ykyi.net/2019/10/rust%E4%B8%AD%E7%9A%84str%E5%92%8Cstring%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/

Leave a Reply

Your email address will not be published. Required fields are marked *