剖析Rust中的str和String之间的区别与共性
之前写代码的时候发现自己其实完全不懂String和str之间的区别,现在写篇文章来细 🔒
首先查看官方参考文档中对 String 的描述如下
The
Stringtype 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::strprimitive module.The
&strtype is one of the two main string types, the other beingString. Unlike itsStringcounterpart, 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之间的区别与共性/