剖析Rust中的str和String之间的区别与共性
之前写代码的时候发现自己其实完全不懂String
和str
之间的区别,现在写篇文章来细 🔒
首先查看官方参考文档中对 String 的描述如下
The
String
type is the most common string type that has ownership over the contents of the string. It has a close relationship with its borrowed counterpart, the primitivestr
.
我们可以发现 String
是拥有字符串内容的所有权的,而 str
则被描述为“借用”。查看具体实现的源代码,有如下的实现内容:
1 | pub struct String { |
也就是说,String 是确确实实有“拥有”这个字符串内容的。而 str
在参考文档中被描述为如下的内容:
Unicode string slices.
See also the
std::str
primitive module.The
&str
type is one of the two main string types, the other beingString
. Unlike itsString
counterpart, its contents are borrowed.
string slices 意为字符串切片,那么说明一般 str
类型是作为指针,描述一个字符串切片的存在,而作为一个 primitive type,无法找到其具体内容实现,但是可以确定的是,它并没有对指向内容的所有权,但是由于往往作为引用 &str
存在,因此有着更高的灵活性与便捷度。
关于字符常量
我们常常会使用类似于如下的代码创建 String
以及 &str
变量:
1 | let a_string = String::from("驻留字符串"); |
学习 Java 虚拟机时就学习过,虚拟机会将编译得到的字符串驻留(interned)
,即,提前为不可变字符串在全局区域分配空间,如果有多个相同引用只需要实际创建一次即可。
我们可以看到,不论是上面的 a_string
还是下面的 a_str
,都使用了相应的字符串常量,分别分配了两段内容为驻留字符串
和这是字符串常量
的文本于内存中,同时,String::from
的实现为:
1 | // String::from |
继续追溯:
1 | // str::into_string |
我们发现,String::from
其实是根据字符串常量内容自行 alloc 了相同的空间,并且将内容复制到该空间内(在堆空间内)。
总结
对于希望拥有字符串所有权,需要更大程度地掌控字符串,请使用 String
类型,而如果是作为一个不会更改的常量存在,则应该使用 str
类型进行操作。
剖析Rust中的str和String之间的区别与共性
https://hyiker.github.io/2021/03/05/剖析Rust中的str和String之间的区别与共性/