在原始人is about slices上进行的沙沙练习之一.

当我试图解决这个练习时,我首先使用[start...end]语法将一个片段放入给定的数组中

fn slice_out_of_array() {
    let a: [u8; 5] = [1, 2, 3, 4, 5];
    let nice_slice = a[1..4];
    assert_eq!([2, 3, 4], nice_slice)
}

编译器抱怨并告诉我:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> exercises/primitive_types/primitive_types4.rs:10:9
   |
10 |     let nice_slice = a[1..4];
   |         ^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `[u8]`
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature
help: consider borrowing here
   |
10 |     let nice_slice = &a[1..4];
   |                      +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

rustc --explain E0277分并不能真正回答我的问题.它解释了当函数指定应该实现特征时,参数不实现特征意味着什么.这对我来说是清楚的,但我不完全清楚这里出了什么问题.

这就是我正在发生的事情,但我想听听别人的意见.

  1. 编译器无法从Slice语法计算出结果片有多大,因此它无法在堆栈上分配适当的空间.

  2. 默认情况下,片是基本类型,驻留在堆栈而不是堆上.

  3. 如果我接受建议并添加&,编译器将在堆栈上推送对堆栈上已有的原始数组的引用--该引用具有已知的大小.这就解决了问题.

这样对吗?有没有这样一种情况,我可以取一片而不加&符号?

推荐答案

编译器无法从Slice语法计算出结果片有多大,因此它无法在堆栈上分配适当的空间.

这是真的.我们说切片是Dynamically Sized Types (DSTs),或者是they are not 101,或者是they do not implement the 101 trait(这就是rustc提供E0277的原因,类型不实现特征).

默认情况下,片是基本类型,驻留在堆栈而不是堆上.

这并不精确:切片是基元,但Rust基元与任何其他对象一样,也可以驻留在堆上.这只是因为您正在try 移动它,所以编译器需要在堆栈上为它保留空间.

如果我接受建议并添加&,编译器将在堆栈上推送对堆栈上已有的原始数组的引用--该引用具有已知的大小.这就解决了问题.

是.从本质上讲,编译器只是偏置地址并缩短长度.对切片的引用是一对(地址,长度).

有没有这样一种情况,我可以取一片而不加&符号?

是也不是.

不,因为你总是带着某种推荐信.所有DST只能位于间接引用(引用、BoxRc...)之后.

但也是这样的,因为你并不总是需要添加&符号.有时编译器会为您做这件事:当您在片上调用方法时,这要归功于autoref:

fn slice_out_of_array() {
    let a: [u8; 5] = [1, 2, 3, 4, 5];
    a[1..4].is_empty(); // Just an example. Equivalent to:
    (&a[1..4]).is_empty();
}

您也可以将其移动到堆中(但这也需要在幕后引用):

fn slice_out_of_array() {
    let a: [u8; 5] = [1, 2, 3, 4, 5];
    let b: Box<[u8]> = a[1..4].into();
}

Rust相关问答推荐

在Rust中创建可变片段的可变片段的最有效方法是什么?

在泛型 struct 的字段声明中访问关联的Conant

为什么BitVec缺少Serialize trait?

关于如何初始化弱 struct 字段的语法问题

为什么允许我们将可变引用转换为不可变引用?

如何go 除铁 rust 中路径组件的第一项和最后一项?

原始数组数据类型的默认trait实现

在使用AWS SDK for Rust时,如何使用硬编码访问密钥ID和密钥凭据?

一次不能多次borrow *obj作为可变对象

Rust 文件未编译到 dll 中

相当于 Rust 中 C++ 的 std::istringstream

如何保存指向持有引用数据的指针?

在发布中包含 Rust DLL

使用在功能标志后面导入的类型,即使未启用功能标志

使用方法、关联函数和自由函数在 Rust 中初始化函数指针之间的区别

仅当满足外部条件时如何添加到 actix web 的路由

我如何将 google_gmail1::Gmail> 传递给线程生成?

Rust HRTB 是相同的,但编译器说一种类型比另一种更通用

为实现特征的所有类型实现显示

如何创建动态创建值并向它们返回borrow 的工厂?