可以说是分配了一个切片文字的行
let integers: [i32] = [ 1, 2, 3 ][..];
字符串
给出了一条消息:integers
“doesn’t have a size known at compile-time”。为什么三个i32
和一个usize
不需要存储空间?是我的想法错了,还是为什么编译器看不到这一点?
可能相关的是https://doc.rust-lang.org/reference/types/slice.html说“切片类型通常通过指针类型使用。”我的猜测是,这个一般规则是强制执行的,当前编译器简单地不允许使用没有间接的切片,但相关的编译器消息是误导性的;所以类型策略,而不是大小是这里问题的核心。(从@colonel-thirty-two的回答In Rust, why is '[T]' and 'str' slice type not a syntax error?中,我了解到这可能在不久的将来发生变化。
我还注意到https://doc.rust-lang.org/rust-by-example/primitives/array.html没有讨论[T],而是讨论&[T]。
1条答案
按热度按时间mgdq6dx11#
Rust在编译时使用类型来传递信息。事实上,如果让Rust推断if
[1, 2, 3]
的类型,它会告诉你它是一个[i32; 3]
,一切都会正常工作。通过将[i32; 3]
强制转换为[i32]
,可以强制编译器丢失有关数组大小的信息。此外,请注意,
[1, 2, 3]
* 不 * 存储三个i32
和一个usize
,而只是三个i32
。Rust做出了(非常合理的)选择,将未调整大小的类型的大小(以及其他信息,如果需要的话)存储在指向该数据的指针旁边,而不是在该数据中。这允许任意切片而不复制任何数据。在Rust中,这些指针被称为“fat pointers”。最后,未调整大小的类型不一定在指针后面。例如,如果你要创建一个结构体,它的最后一个字段可以是未调整大小的类型:
字符串
这种特殊限制的原因是未调整大小的类型不是一个完成的特性,并且由于完成它没有太大的压力,它可能会在这种半成品状态中停留一段时间。
此外,rust目前不允许存储在堆栈上的值(包括变量)具有未调整大小的类型,但这只是一个临时限制,并且有一个WIP feature来消除此限制。
此外,unsized类型在某种程度上是Rust所独有的。在大多数其他类型语言中,没有这样的东西。所有类型 * 必须 * 在编译时定义大小,或者(例如在C中),大小未知的类型根本无法示例化。