Как сказать компилятору, что внутреннее поле реализует черты или что черта generi c имеет только 2 варианта? - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть 2 типа низкого уровня, State и Base. State s может быть observe d, но в зависимости от точки зрения, некоторые видят полный State, а другие видят только Base.

State составляет основу для типов более высокого уровня , но я не могу найти способ проверить это неоднозначное observe поведение.

Вот попытка реализовать его обобщенно и с простой чертой impl:

// Those two things can be observed..
struct State;
struct Base;

// .. but from 2 different views.
trait Observable<Obs> {
    fn observe(&self) -> Obs;
}
// Some view states as states.
impl Observable<State> for State {
    fn observe(&self) -> State {
        State {}
    }
}
// Some view states as bases.
impl Observable<Base> for State {
    fn observe(&self) -> Base {
        Base {}
    }
}

// States serve as basis for other types..
struct Container {
    field: State,
} // .. there are quite a few like this one.

// Now, when it's time to observe the inner state of the container..
fn process<Obs>(state: &impl Observable<Obs>, container: &Container) -> (Obs, Obs) {
    (
        state.observe(), // (this typechecks fine)
        // .. how to annotate this so the compiler is confident that
        // container.field *does* implements Observable<Obs>?
        container.field.observe(),
    )
}

fn main() {
    // Build up data.
    let s = State {};
    let c = Container { field: State {} };
    // And observe it.
    let o_full: (State, State) = process(&s, &c);
    let o_partial: (Base, Base) = process(&s, &c);
}

получая ошибку

error[E0277]: the trait bound `State: Observable<Obs>` is not satisfied
  --> src/main.rs:33:25
   |
33 |         container.field.observe(),
   |                         ^^^^^^^ the trait `Observable<Obs>` is not implemented for `State`

Я уверен, что этого можно достичь с помощью обобщений и мономорфизации, потому что все статически известно.

Я также вроде понимаю, почему компилятор беспокоится, что Observe<Obs> может не быть реализовано в State для любого типа Obs.

Но здесь нет информации о компиляторе, потому что я все еще знаю больше, чем:

  • Как сказать компилятору, что тип <Obs> generi c будет когда-либо только State или Base?

  • Как сделать для компилятора очевидным, что второй параметр process имеет тип Container, поэтому container.field имеет тип State, и это реализует Observable<Obs>?

1 Ответ

1 голос
/ 07 апреля 2020

Может быть, я что-то упускаю, но не могли бы вы заявить, что State реализует Observable<Obs>? Т.е.:

fn process<Obs>(state: &impl Observable<Obs>, container: &Container) -> (Obs, Obs)
    where State: Observable<Obs> // <--- tell compiler that State satisfies Observable<Obs>
{
    (
        state.observe(),
        container.field.observe(),
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...