下面的代码编译:
fn main() {
let slices:&[i32] = &[1,2,3];
let subSlice = &slices[1..3];
print!("{:?}\n",subSlice);
}
字符串
但这失败了:
fn main() {
let slices:&[i32] = &[1,2,3];
let subSlice = slices[1..3];
print!("{:?}\n",subSlice);
}
Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> src/main.rs:3:9
|
3 | let subSlice = slices[1..3];
| ^^^^^^^^ doesn't have a size known at compile-time
的数据slices
已经是用&
创建的切片/引用(&[i32]
)。为什么我必须在&slices[1..3]
中再次使用&
?
3条答案
按热度按时间raogr8fs1#
从语言的Angular 来看,对切片的索引访问是根据
Index<Idx>
trait实现的。该特征被定义为:
字符串
现在看起来使用this应该返回对索引元素的引用。
事实上,如果我们直接调用它:
型
返回的类型确实是
&[i32]
。(playground link)然而,Index documentation page告诉我们:
container[index]实际上是 *container.index(index)的语法糖
这意味着在您的示例中,返回的切片会自动解引用到一个
[i32]
中,它是未调整大小的。因此,您需要手动借用它以获得&[i32]
。l0oc07j22#
这里的主要问题是当你索引
slices
变量时,它返回的[i32]
不是固定长度的。在这个trait实现中可以看到,它返回
[T]
而不是&[T]
所以编译器不知道要分配多少内存。编译器告诉你,“嘿,我不知道长度,但我知道的是指针的大小”(一个不可变的引用)。
所以编译器建议你借用
[i32]
,所以最终的类型是&[i32]
。这是一个固定长度的指针,因此编译器可以将内存分配到堆栈中。oxcyiej73#
切片通常具有类型[T],没有大小的指示。例如,[i32]没有附加大小信息(例如,与具有[i32; 3],其中3表示大小)。rust在编译时需要大小信息。所以这意味着一个切片必须总是在一个引用后面(因为一个引用有固定的大小,也就是说它是一个指向某个内存的指针)。