【发布时间】: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。
【问题讨论】: