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

标签 arrays rust traits

请考虑以下 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尽管后者是一个特征绑定(bind)。烧了很多时间后,我才发现其实T::BAR在其他上下文中是一个完全有效的表达式,只是不能作为数组的长度参数。

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

A fixed-size array, denoted [T; N], for the element type, T, and the non-negative compile-time constant size, N.

最佳答案

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

a perfectly valid expression in other contexts, just not as a length parameter to an array


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

this is not a particularly good error message


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

I would expect some restriction akin to constexpr


这本质上是限制,问题是允许在 const 中使用什么目前受到高度限制。值得注意的是,这些是不允许的:
  • 函数(构造枚举或结构除外)
  • 循环
  • 多个语句/ block

  • 良好的常量/编译时评估工作仍在进行中。有大量的 RFC、问题和 PR 改进了这一点。一个 sample :
  • Const fn tracking issue (RFC 911)
  • Allow locals and destructuring in const fn (RFC 2341)
  • Allow if and match in constants (RFC 2342)
  • 关于arrays - [_; 中允许哪些表达式作为数组长度 N N]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59506459/

    相关文章:

    rust - 代码无需借用即可工作,但我无法通过借用使其工作

    c++ - 在模板化函数中调用具有特征的显式构造函数/析构函数

    scala - 案例分类和特征

    ios - 无法在 Swift xcode 6.3.1 中使用类型为 'functionName' 的参数列表调用 '([(nameOfClass)])'

    java - 创建脚本以重新启动主机名位于文本文件中的计算机

    rust 语法匹配绑定(bind) - 如何将 "Some"与条件和无匹配在一起

    rust - 我怎样才能在原始 crate 中使用另一个 crate 中的特征实现?

    java - 如何从先前定义的两个不同整数数组中输出相同的数字

    翻转列表/元组的pythonic方式

    rust - 装箱列表的第一个 Cons 是否在堆栈上?