允许哪些表达式作为[_;中的数组长度N N]?

Jon*_*ann 3 arrays traits rust

请考虑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();
}
Run Code Online (Sandbox Code Playgroud)

编译器给出以下错误:

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`
Run Code Online (Sandbox Code Playgroud)

无论我的问题的答案是什么,这都不是一个特别好的错误信息,因为它表明尽管后者是一个特征限制,TFoo仍然可以实现.只有在经过大量的时间之后,我才发现它实际上T::BAR是在其他上下文中完全有效的表达式,而不是作为数组的长度参数.

什么样的表达可以用来管理哪些规则?因为数组是Sized,我完全理解在编译时要知道长度.我自己来自C++,我希望有一些类似的限制,constexpr但我没有在它刚才说的文档中遇到过

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

She*_*ter 6

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

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

通用关联的consts目前无法用于参数化固定的数组长度(#42863)

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

对于数组长度中的关联consts,应该改进错误消息(#44168)

我期待一些限制类似于 constexpr

本质上的限制,问题是,什么是允许的使用const在目前的高度限制.值得注意的是,这些是不允许的:

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

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