为什么 rust 有StringstrStringstr之间有什么区别?什么时候用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 viewString的数据.

  • 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.

Rust相关问答推荐

异步函数返回的future 生存期

变量需要parse()中的显式类型

如何在不调用Collect()的情况下为新型vec实现IntoIterator?

为什么`tokio::main`可以直接使用而不需要任何导入?

std::vector::shrink_to_fit 如何在 Rust 中工作?

如何在 Rust 中将枚举变体转换为 u8?

在 Rust 中实现资源消耗的安全包装器

类型判断模式匹配panic

是否可以在 Rust 中的特定字符上实现特征?

在空表达式语句中移动的值

需要括号的宏调用中的不必要的括号警告 - 这是编写宏的糟糕方法吗?

Rust 生命周期:不能在方法内重新borrow 可变字段

为什么可以从不可变 struct 的字段中移动?

将 reqwest bytes_stream 复制到 tokio 文件中

Rust 包装器类型的范围?

嵌套 FnMut 返回对已捕获变量的引用,该变量逃脱了闭包体

为什么我需要在等待对它的引用之前固定一个future ?

用于在 Rust 中实现 len() 函数的类型的通用更长函数

循环声明内的互斥锁

在没有明确调用 unwrap/panic 的情况下,rust 可能会panic 的所有方式是什么?