在Rust中如何覆盖通用trait实现

4

对于我的游戏规则引擎,我有一个名为Rule的中央特征来处理游戏回调。存在两种类型的Rule:一个BaseRule适用于游戏中的任何实体,而CreatureRule仅适用于生物。我目前将代码结构化如下:

trait BaseRule<T> {
    fn on_turn_start(&self, owner: &T) {}
}

#[typetag::serde(tag = "type")]
pub trait CreatureRule: BaseRule<Creature> {
    fn on_death(&self, owner: &Creature) {}
}

这很好用,但有点烦人,因为你需要为每个实现都实现 RuleCreatureRule。我尝试做一个 BaseRule 的通用实现:
impl<R: CreatureRule> BaseRule<Creature> for R {
}

但是,如果我尝试通过以下方式添加一个BaseRule trait 的新实现,这将导致冲突:

impl BaseRule<Creature> for BaseMeleeDamageAttack {
    fn on_turn_start(&self, owner: &Creature) {
        // do stuff
    }
}

由于同一特质不能有两个实现,那么我是否可以向实现了 CreatureRule 的类型提供 BaseRule 的默认实现,同时允许它们重写函数的默认实现呢?

(如果有可能,我希望避免在 CreatureRule 上使用泛型类型参数,因为具有泛型类型的特质无法进行 Serde 序列化。)


2
在稳定的 Rust 中,基本上不行。您正在要求特质专门化。 - orlp
请查看 https://github.com/rust-lang/rfcs/pull/1210 和 https://github.com/rust-lang/rust/issues/31844。 - Solomon Ucko
1个回答

2
我认为你需要手动为每个实现它,但只有一行代码:
impl BaseRule<Creature> for ... {}

自动实现需要使用宏(这会使代码不易读),或者impl特化(参见rust-lang/rfcs#1210rust-lang/rust#31844),但目前需要使用nightly版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接