[_; 中的数组长度 N 允许使用什么表达式? N]?
What expressions are allowed as the array length N in [_; N]?
请考虑以下 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
,尽管后者是一个 trait bound。只有在燃烧了很多时间之后,我才想到实际上 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
的“常规”常量。今天存在少量常量求值,但 more-or-less 仅限于基础数学。
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
中使用的内容受到高度限制。值得注意的是,这些是不允许的:
- 函数(构造枚举或结构除外)
- 循环
- 多个语句/块
关于 good constant 的工作/compile-time 评估仍在进行中。有大量的 RFC、问题和 PR 对此进行了改进。样本:
请考虑以下 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
,尽管后者是一个 trait bound。只有在燃烧了很多时间之后,我才想到实际上 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
的“常规”常量。今天存在少量常量求值,但 more-or-less 仅限于基础数学。
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
中使用的内容受到高度限制。值得注意的是,这些是不允许的:
- 函数(构造枚举或结构除外)
- 循环
- 多个语句/块
关于 good constant 的工作/compile-time 评估仍在进行中。有大量的 RFC、问题和 PR 对此进行了改进。样本: