【问题标题】:What expressions are allowed as the array length N in [_; N]?[_; 中允许哪些表达式作为数组长度 N N]?
【发布时间】:2018-03-24 18:07:42
【问题描述】:

请考虑以下 Rust 中的最小示例:

const FOOBAR: usize = 3;

trait Foo {
    const BAR: usize;
}

struct Fubar();

impl Foo for Fubar {
    const BAR: usize = 3;
}

struct Baz<T>(T);

trait Qux {
    fn print_bar();
}

impl<T: Foo> Qux for Baz<T> {
    fn print_bar() {
        println!("bar: {}", T::BAR);   // works
        println!("{:?}", [T::BAR; 3]); // works
        println!("{:?}", [1; FOOBAR]); // works
        println!("{:?}", [1; T::BAR]); // this gives an error
    }
}

fn main() {
    Baz::<Fubar>::print_bar();
}

编译器给出以下错误:

error[E0599]: no associated item named `BAR` found for type `T` in the current scope
  --> src/main.rs:24:30
   |
24 |         println!("{:?}", [1; T::BAR]); // this gives an error
   |                              ^^^^^^ associated item not found in `T`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `BAR`, perhaps you need to implement it:
           candidate #1: `Foo`

无论我的问题的答案是什么,这都不是一个特别好的错误消息,因为它表明T 确实实现了Foo,尽管后者是一个特征绑定。我花了很多时间才发现,事实上T::BAR 在其他上下文中是一个完全有效的表达式,只是不能作为数组的长度参数。

有什么规则可以控制什么样的表达式可以去那里?因为数组是Sized,所以我完全理解在编译时要知道长度。我自己来自 C++,我预计会有一些类似于 constexpr 的限制,但我在 documentation 中没有遇到过它只是说的地方

一个固定大小的数组,表示为 [T; N],用于元素类型 T 和非负编译时常量大小 N。

【问题讨论】:

    标签: arrays rust traits


    【解决方案1】:

    从 Rust 1.24.1 开始,数组长度基本上需要是数字文字或 usize 的“常规”常量。今天存在少量的持续评估,但它或多或少仅限于基础数学。

    在其他上下文中完全有效的表达式,只是不能作为数组的长度参数

    Array lengths don't support generic parameters. (#43408)

    这不是一个特别好的错误信息

    Error message should be improved for associated consts in array lengths (#44168)

    我希望有一些类似于constexpr的限制

    这是本质上是限制,问题是在const 中允许使用的内容目前受到高度限制。值得注意的是,这些是不允许的:

    • 函数(构造枚举或结构除外)
    • 循环
    • 多个语句/块

    关于良好常量/编译时评估的工作仍在进行中。有大量的 RFC、问题和 PR 改进了这一点。一个样本:

    【讨论】:

      猜你喜欢
      • 2013-01-19
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      相关资源
      最近更新 更多