为什么 rust 有String
和str
?String
和str
之间有什么区别?什么时候用String
而不是str
,反之亦然?他们中有人不赞成吗?
为什么 rust 有String
和str
?String
和str
之间有什么区别?什么时候用String
而不是str
,反之亦然?他们中有人不赞成吗?
String
是动态堆字符串类型,如Vec
:需要拥有或修改字符串数据时使用它.
str
是内存中某个地方动态长度的UTF-8字节的不可变1序列.由于大小未知,只能在指针后面处理.这意味着str
最常见的2显示为&str
:对一些UTF-8数据的引用,通常称为"字符串切片"或只是"切片".A slice只是一些数据的视图,这些数据可以在任何地方,例如.
In static storage:字符串文字"foo"
是&'static str
.数据被硬编码到可执行文件中,并在程序运行时加载到内存中.
Inside a heap allocated 101:String
dereferences to a &str
view的String
的数据.
On the stack:例如,下面创建一个堆栈分配的字节数组,然后得到一个view of that data as a &str
:
use std::str;
let x: &[u8] = &[b'a', b'b', b'c'];
let stack_str: &str = str::from_utf8(x).unwrap();
总之,如果需要拥有的字符串数据(比如将字符串传递给其他线程,或在运行时构建它们),请使用String
;如果只需要字符串的视图,请使用&str
.
这与向量Vec<T>
和切片&[T]
之间的关系相同,并且与一般类型的by value T
和by reference &T
之间的关系相似.
1A str
为固定长度;不能将字节写在结尾之外,也不能留下尾随的无效字节.由于UTF-8是一种可变宽度编码,这实际上迫使所有str
在许多情况下都是不可变的.一般来说,Mutations 需要写入比以前更多或更少的字节(例如,用ä
(2+字节)替换a
(1字节)需要在str
中留出更多空间).有一些特定的方法可以就地修改&mut str
,大多数方法只处理ASCII字符,比如make_ascii_uppercase
.
2 Dynamically sized types allow things like Rc<str>
for a sequence of reference counted UTF-8 bytes since Rust 1.2. Rust 1.21 allows easily creating these types.