What are the differences between Rust's `String` and `str`?的答案描述了&str
和String
之间的关系。
令人惊讶的是,str
比固定大小的数组有更多的限制,因为不能将其声明为局部变量。编译
let arr_owned = [0u8; 32];
let arr_slice = &arr_owned;
let str_slice = "apple";
let str_owned = *str_slice;
在Rust 1.32.0中,我得到了
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> src/lib.rs:6:9
这令人困惑,因为编译器可以知道"apple"
的大小,因此它不是str
类型的一部分。
在Vec<T>
<-> [T; N]
和String
和-str
所拥有的类型之间存在不对称性的语言原因吗?是否可以将str[N]
简化为[u8; N]
的类型,而该str
类型仅包含经过验证的有效UTF-8编码的字符串,而不替换大量现有代码的/WEB-INF/some_file/some.bin
?
答案 0 :(得分:9)
Vec<T>
<->[T; N]
和String
之间的不对称性<->str
那是因为您在这里有些困惑。这种关系是这样的:
Vec<T>
⇔[T]
String
⇔str
在所有这四种类型中,长度信息是在运行时而不是编译时存储的。固定大小的数组([T; N]
)在这方面有所不同:它们在编译时存储长度,而不在运行时存储长度!
实际上,[T]
和str
都不能存储在堆栈中,因为它们都没有大小。
str[N]
是仅包含可证明有效的UTF-8编码字符串的[u8; N]
的简写形式,可以替换str
而不破坏很多现有代码吗? >
它不会替代str
,但确实是一个有趣的补充!但是,可能有一些原因导致其不存在,例如因为the length of a Unicode string is usually not really relevant。特别是,“采用一个正好三个字节的Unicode字符串”通常没有意义。
答案 1 :(得分:5)
[T]
和str
无法存储在堆栈中,因为它们都没有大小
虽然今天是正确的,但将来可能并非如此。 RFC 1909 introduces unsized rvalues。此功能将赋予的权力之一是variable-length arrays:
RFC还描述了数组文字语法的扩展:
[e; dyn n]
。在语法中,n
不一定是常量表达式。数组是动态分配在堆栈上
没有提及是否可以直接使用字符串,但是总是可以创建一个堆栈分配的字节数组来用作字符串存储。