当前位置: 代码迷 >> 综合 >> rust 中的 String 和 str
  详细解决方案

rust 中的 String 和 str

热度:85   发布时间:2023-12-12 15:31:05.0

1. str 和 &str

 看下面的代码:

let s = "hello";

其中,"hello" 的数据类型是 str,变量 s 的数据类型是 &str。有点难理解,我们可以与 c 语言比较,然后就容易理解了。上面的代码在 c 语言中是下面的样子:

char *s = "hello"; 

 很有意思吧? 在 c 语言中, s 是指针。但是,变量 s 用起来很不安全,因为不知道 s 指向的数据占用了多少内存空间。

于是在 rust 中,s 是切片。切片是一个结构体,包含两个字段,一个是指向数据的指针,另一个是数据的长度。因此,我们有可能采用必要的措施,安全的使用变量 s。

2. String

切片 &str 虽然可以安全使用,但是,我们很难动态修改其内容 —— 其地址、长度都是固定的。于是 rust 提供了数据类型 String。

String 包含了数据指针、数组容量、数据长度等三个字段。如果新修改的数据长度在其容量范围内,数据可以原地修改。如果新修改的数据长度超出了容量范围,它可以重新申请更大的内存。

于是我们看到,String 和 &str 是两个完全不一样的结构体。为什么字符串要保留这两种形式?原因就是效率。rust 希望在数组容量不会变化的时候,用 &str。在数组长度可能发生变化的情况下,使用 String。

3. &str 转 String 

可以用 &str 的 to_string() 方法,或者用 String::from() 方法。例如:

let s: String = "hello".to_string();
let t: String = String::from("hello");

4. String 转 &str

这个很有意思,在 rust 中,凡是需要用 &str  的地方,都可以直接用 &String 类型的数据。例如:

fn greet(s: &str) {...
}fn main() {let s: String = String::from("hello");greet(&s);
}

难道 rust 故意为 String 设计了这么一个机关? 如果这样的话,rust 内部岂不打破了某种简单化的设计原则?事实上,上述转换是借助于 deref coercing 这个特性实现的。如果我们自定义的数据类型也想实现类似的自动转换,实现这个特性即可。

5. 何时使用 $str,何时使用 String?

规则很简单,一般情况下,&str 用于只读数据,String 用于可修改的数据。至于特殊情况,你自己应该会选择的。

  相关解决方案