简体   繁体   English

为什么 Rust 从特征到特征分配 const 不起作用?

[英]Why does Rust assignment of const from trait to trait not work?

I'm trying to assign an associated const defined in one trait to another trait which doesn't work as expected.我正在尝试将一个特征中定义的关联常量分配给另一个无法按预期工作的特征。 Here's a minimal example with 3 traits and one struct:这是一个包含 3 个特征和一个结构的最小示例:

trait A {
    const X: i32 = 1;
}

struct S;

impl A for S {}

trait B {
    const Y: i32 = A::X;
}

trait C {
    const Y: i32 = S::X;
}

fn main() {}

The corresponding compiler error is:对应的编译错误是:

error[E0283]: type annotations required: cannot resolve `_: A`
  --> src/main.rs:10:20
   |
10 |     const Y: i32 = A::X;
   |                    ^^^^
   |
note: required by `A::X`
  --> src/main.rs:2:5
   |
2  |     const X: i32 = 1;
   |     ^^^^^^^^^^^^^^^^^

The explanation for E0283 tells me what the code reveals: I can assign from a concrete type but not the trait itself. E0283的解释告诉我代码所揭示的内容:我可以从具体类型进行分配,但不能从特征本身进行分配。 But where the E0283 example uses an undefined function I have an already defined value.但是在E0283示例使用未定义函数的地方,我有一个已经定义的值。 Why is that so and how can this be bypassed?为什么会这样,如何绕过?

The problem is that any struct that implements A could define its own value for X .问题是任何实现A struct都可以为X定义自己的值。 Thus, simply stating A::X in the context of trait B does not offer enough information for the compiler as to which impl of A should be chosen.因此,在trait B的上下文中简单地声明A::X并不能为编译器提供足够的信息,说明应该选择A哪个impl

If you want that something that impl ements B also impl ements A , you can try the following (I have no compiler at hand, but the idea should be clear):如果您希望impl B东西也impl A ,您可以尝试以下操作(我手头没有编译器,但想法应该很清楚):

trait B : A {
    const Y: i32 = <Self as A>::X;
}

Traits are supposed to be implemented by a concrete type, and are not supposed to define a constant on their own that can't be changed in implementors. Traits 应该由一个具体的类型来实现,而不应该自己定义一个不能在实现者中改变的常量。 What you specified is a default value, rather than a value all implementors must adhere to.您指定的是默认值,而不是所有实现者必须遵守的值。 You wouldn't need a trait if all types must have the same X value.如果所有类型都必须具有相同的X值,则不需要特征。

Therefore A::X is not a well defined value.因此A::X不是一个明确定义的值。

Here is an example showing why:这是一个说明原因的示例:

trait A {
    const X: i32 = 1;
}

struct S;

impl A for S {}

struct R;

impl A for R {
    const X: i32 = 42;
}

fn main() {
    println!("S: {}", S::X);
    println!("R: {}", R::X);
    println!("S: {}", <S as A>::X); // A::X alone is ambiguous
    println!("R: {}", <R as A>::X);
}

(link to playground) (链接到游乐场)

What you are doing is similar to trying to call a default function on a trait, here the error E0283:您正在做的类似于尝试在特征上调用默认函数,这里是错误 E0283:

trait A {
    fn get_x() -> i32 {
        1
    }
}

struct S;

impl A for S {}

struct R;

impl A for R {
    fn get_x() -> i32 {
        42
    }
}

fn main() {
    // A::get_x() is ambiguous but there are not:
    println!("S: {}", S::get_x());
    println!("R: {}", R::get_x());
    println!("S: {}", <S as A>::get_x());
    println!("R: {}", <R as A>::get_x());
}

(link to playground) (链接到游乐场)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM