6

rust 中 str 与 String; &str &String - Aitozi

 1 year ago
source link: https://www.cnblogs.com/Aitozi/p/17406915.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

String

String 类型的数据和基本类型不同,基本类型的长度是固定的,所以可以在栈上分配,而String类型是变长的,所以需要在堆上分配,所以String 类型实际上是一个指向堆的指针。他的结构和Vec很类似。从他的声明看也是一个u8的Vec

pub struct String { vec: Vec<u8>,}

看这样一个定义: Programming Rust 2nd Edition 第三章

image.png
image.png

通过字面量声明的是一个 &str。通过to_string 方法转成一个String类型。
如果是一个字面量,那实际上是程序中预先分配好的只读内存,如上面的poodles。
String类型是一个 **拥有堆上数据所有权 **的指针,包含了capacity 和 长度
&str 是堆上数据的一个 切片,并不拥有数据。当执行to_string 的时候,会将数据拷贝到堆上

image.png

str和&str

下面定义四种不同的类型

image.png
image.png

这里会有一个编译报错,提示 str 类型在编译期无法知道其大小。
上面说过 str 实际上是 堆上数据的一个切片,所以其类型 应该是 [u8]如下面的一个 Vec<i32> 的一个切片的类型就是 [i32]
而由于slice可以是任意长度,所以slice类型不可以直接存储在变量中(不确定长度的数据没法保存在栈上)。所以slice的数据都是以reference&的形式在使用。
以vec为例

image.png
image.png

指向一个slice的ref是2字节长度,第一个字节保存了slice第一个元素的指针,第二个字节保存了slice的长度。
所以str类型是String的切片类型一般无法直接交互,&str是切片类型的引用。
另外对于 str 类型,虽然不能直接交互,但是可以在上面定义方法,比如上面提到的to_string方法

image.png

&String

通常来说 String 在栈上分配,数据存储在堆上,而&String是指向 String 的引用。&String 有点类似于&str 不过 &str直接指向了 切片的第一个元素,而&String首先指向了String,再指向heap,感觉开销会更大一些? 不过可能编译期会处理掉这个开销。总之看起来 &String没有什么使用需求。

再对比下Java 中的String,实际Java的String对象和基本对象不同,也是一个引用所以可以存储在栈上,而String内部存储数据的是一个byte[]数组。Java String对象本身也是不可变的,修改字符串会重写在堆上分配内存重写新的。
Java中除了基本类型,其他类型都是引用类型,屏蔽了内部这些细节,而rust中对这些做了区分,交给用户来进行处理。

除了String之外,rust中的字符串相关的类型还有

image.png

https://www.reddit.com/r/rust/comments/fgpdb0/trying_to_understand_str_vs_str_t_vs_t_osstr_vs/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK