Почему назначение Rust const от черты к черте не работает? - PullRequest
1 голос
/ 22 июня 2019

Я пытаюсь присвоить связанный констант, определенный в одной черте, другой черте, которая не работает, как ожидалось.Вот минимальный пример с 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() {}

Соответствующая ошибка компилятора:

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;
   |     ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.

Объяснение для E0283 говорит мне, что показывает код: я могу назначить изконкретный тип, но не сама черта.Но где в примере E0283 используется неопределенная функция, у меня уже есть определенное значение.Почему это так и как это можно обойти?

Ответы [ 2 ]

3 голосов
/ 22 июня 2019

Проблема в том, что любой struct, который реализует A, может определить свое собственное значение для X. Таким образом, простое указание A::X в контексте trait B не дает достаточной информации компилятору о том, какой impl из A должен быть выбран.

Если вы хотите что-то, что impl также B * impl или A, вы можете попробовать следующее (у меня нет под рукой компилятора, но идея должна быть ясна):

trait B : A {
    const Y: i32 = <Self as A>::X;
}
2 голосов
/ 22 июня 2019

Черты должны быть реализованы конкретным типом и не должны определять константу самостоятельно, которая не может быть изменена в разработчиках. То, что вы указали, является значением по умолчанию, а не значением, которого должны придерживаться все разработчики. Вам не нужна черта, если все типы должны иметь одинаковое значение X.

Следовательно, A::X не является четко определенным значением.

Вот пример, показывающий, почему:

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);
}

(ссылка на игровую площадку)

То, что вы делаете, похоже на попытку вызова функции по умолчанию для признака, здесь ошибка 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());
}

(ссылка на игровую площадку)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...