为什么固定大小的数组可以放在堆栈上,但是str不能呢?

时间:2019-02-13 14:58:24

标签: rust language-lawyer

What are the differences between Rust's `String` and `str`?的答案描述了&strString之间的关系。

令人惊讶的是,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

2 个答案:

答案 0 :(得分:9)

  

Vec<T> <-> [T; N]String之间的不对称性<-> str

那是因为您在这里有些困惑。这种关系是这样的:

  • Vec<T>[T]
  • Stringstr

在所有这四种类型中,长度信息是在运行时而不是编译时存储的。固定大小的数组([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不一定是常量表达式。数组是动态分配在堆栈上

没有提及是否可以直接使用字符串,但是总是可以创建一个堆栈分配的字节数组来用作字符串存储。