Rust 中 String &String str &str 的区别

4,112 阅读2分钟

str &str 与 String

参考地址:rust-book.junmajinlong.com/ch3/04_str_…

String &String str &str 类型解释

String &String

String 类型的字符串是分配在堆上内存的可变字节缓冲区,可以通过字符串字面量构建,值保存在堆中,变量保存在栈上,是一个胖指针:fat pointer。三个字分别为:

  1. pointer :heap中值的内存地址

  2. length :当前值的长度、当前元素个数。

  3. capacity :当前缓冲区的容量,可以容纳元素的个数,当前字符串的长度超过当前分配的capacity 会重新分配内存,会将当前字符串拷贝到新分配的内存中。

&String 是String类型的引用,实际上保存的是内存地址,默认保存在栈上如果通过Box、vec! 等方法可以分配在堆上。from() 中的字符串是字符串字面量会被打包进二进制文件中,创建 String 类型变量时会先在 ROM 区域中找对应的字符串,然后拷贝到堆中,返回对应的内存地址等信息。

let s = String::from("hello");
let s1 = &s;

下图为上面代码的内存分配图: image_pFgpg0PXFf.png

str &str

在Rust中字符串字面量并不是先在内存中以String类型的方式存储,然后再创建String的引用来得到一个&str。而是以编译器在编译的时候直接将字符串字面量以硬编码的方式写入程序的二进制文件中,当程序被加载时,字符串字面量保存中Read Only Memory 字段中。当程序执行到let s = "hello"; ,将"hello" 赋值给变量s,s在栈上,是直接将"hello" 的地址返回给变量s。如果有两个相同的字符串字面量,其地址是相同的。

let s1 = "hello";
let s2 = "hello";
assert_eq!(*s1, *s2);

内存分配如下图:

image_OuHU2PGEPP.png

s1 和 s2 指向的内存地址相同,该地址中的内存是不可以改变的。

  • 下面的代码解释:

    let s: &str = "hello";
    
    • str 代表 str 类型是一个切片类型不能直接使用。

    • & 表示引用,即一个指针

    • &str 表示指向内存中str类型的指针,该内存保存 str类型的变量值:"hello"&strString 的切片类型。

str 和String的区别:

str 字符串是String类型字符串的切片类型,我们说切片一般使用引用,所以&strString 的切片类型。

如:变量s保存了字符串"hello" ,那么s[0..1] 就是str类型的字符串"h"s[0..3] s[3..] 分别为字符串"hel" "lo"

let s = String::from("hello");
// s[0..1] 的类型为 str是string 的切片类型,不能直接切片,
let s1 = &s[0..1];
let s2 = &s[0..3];
let s3 = &s[3..];

因为不能直接使用str,str 不能在编译时确定类型,Rust不支持。所以使用 str 引用类型 &str。

如图

image_Sa7aGKYgxf.png