如何告诉编译器内部字段实现特征或通用特征只有 2 个变体?
How to tell compiler that inner field implements traits or that generic trait has only 2 variants?
我有 2 个低级类型,State
和 Base
。 State
s 可以是 observe
d,但根据视角的不同,有些人会看到完整的 State
,而其他人只会看到 Base
.
State
构成了高级类型的基础,但我找不到一种方法来检查这种矛盾的 observe
行为。
这里是用通用性和简单的 impl
trait bound 来实现它的归结尝试:
// 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>
泛型类型只会是 State
或 Base
?
如何让编译器明白process
的第二个参数是Container
类型,所以container.field
是State
类型这确实实现了 Observable<Obs>
?
也许我漏掉了什么,但你不能说 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(),
)
}
我有 2 个低级类型,State
和 Base
。 State
s 可以是 observe
d,但根据视角的不同,有些人会看到完整的 State
,而其他人只会看到 Base
.
State
构成了高级类型的基础,但我找不到一种方法来检查这种矛盾的 observe
行为。
这里是用通用性和简单的 impl
trait bound 来实现它的归结尝试:
// 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>
泛型类型只会是State
或Base
?如何让编译器明白
process
的第二个参数是Container
类型,所以container.field
是State
类型这确实实现了Observable<Obs>
?
也许我漏掉了什么,但你不能说 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(),
)
}