如何在 Rust 中定义任一/或特征边界

问题描述 投票:0回答:1
recursion rust traits
1个回答
0
投票

要理解

yew
解决方案,最好要求编译器转储宏扩展的 AST。这样您就可以准确地看到生成的结构和特征是什么。

我不知道这是否正是在

yew
中的工作原理,但类似的东西是有效的,也许一些丑陋的部分可以隐藏在宏中:

use std::marker::PhantomData;

trait HasProperty<P, How> {}

struct Property1;
struct Property2;

struct WithProperty<P, Tail>(PhantomData<P>, Tail);

fn with<P, Tail>(t: Tail) -> WithProperty<P, Tail> {
    WithProperty(PhantomData, t)
}

fn check<P, How>(token: &impl HasProperty<P, How>) {}

struct Directly;
impl<P, Tail> HasProperty<P, Directly> for WithProperty<P, Tail> {}

struct Step<N>(N);
impl<P, P2, Tail, N> HasProperty<P, Step<N>> for WithProperty<P2, Tail> where Tail: HasProperty<P, N> {}

fn main() {
  let token1 = with::<Property1, _>(with::<Property2, _>(()));
  let token2 = with::<Property1, _>(());

  check::<Property1, _>(&token1); // compiles
  check::<Property2, _>(&token1); // compiles
  check::<Property1, _>(&token2); // compiles
  // check::<Property2, _>(&token2); // fails with "the trait bound `(): HasProperty<Property2, _>` is not satisfied"
}

这两个

HasProperty
实现并不重叠,因为它们是针对两个不同的
struct
实现的。
Step
是一个(类似链表的)包装器,指示该属性存在,并且发现
N
会进入
WithProperty
嵌套。

如果你写的是:

with::<Property1, _>(with::<Property2, _>(with::<Property1, _>(())))

然后

check
调用会抱怨多个可能的
impl
。我不知道
yew
是否能更优雅地处理这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.