首页 > 解决方案 > 如何解决“计算超特征时检测到循环”?

问题描述

我有Component一个相关类型的特征Msg

trait Component {
    type Msg;
    fn update(&self, msg: Self::Msg);
}

我对其进行了修改以实现克隆:

trait Component: ComponentClone<Self::Msg> {
    type Msg;
    fn update(&self, msg: Self::Msg);
}

pub trait ComponentClone<T> {
    fn clone_box(&self) -> Box<dyn Component<Msg = T>>;
}

impl<T, M> ComponentClone<M> for T
where
    T: 'static + Component<M> + Clone,
{
    fn clone_box(&self) -> Box<dyn Component<M>> {
        Box::new(self.clone())
    }
}

impl<M: 'static> Clone for Box<dyn Component<M>> {
    fn clone(&self) -> Box<dyn Component<M>> {
        self.clone_box()
    }
}

操场

我收到一个错误:

error[E0391]: cycle detected when computing the supertraits of `Component`
 --> src/lib.rs:1:1
  |
1 | trait Component: ComponentClone<Self::Msg> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: ...which again requires computing the supertraits of `Component`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | trait Component: ComponentClone<Self::Msg> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

如果我尝试使用泛型,一切都会编译(但我确实收到警告):

trait Component<M>: ComponentClone<M> {
    fn update(&self, msg: M);
}

pub trait ComponentClone<T> {
    fn clone_box(&self) -> Box<dyn Component<T>>;
}

impl<T, M> ComponentClone<M> for T
where
    T: 'static + Component<M> + Clone,
{
    fn clone_box(&self) -> Box<dyn Component<M>> {
        Box::new(self.clone())
    }
}

impl<M: 'static> Clone for Box<dyn Component<M>> {
    fn clone(&self) -> Box<dyn Component<M>> {
        self.clone_box()
    }
}

怎么了?如何解决这个问题呢?

标签: rusttraits

解决方案


虽然给出的代码包含其他错误,但我将专注于特定情况下的问题。

当您有一个依赖于所定义特征中关联类型的特征绑定时,请提供关联类型的完整路径(又名 UFCS):

trait Component: ComponentClone<<Self as Component>::Msg> {
    //                          ^^^^^^^^^^^^^^^^^^^^^^^^ use a full path to Msg
    type Msg;
    fn update(&self, msg: Self::Msg);
}

pub trait ComponentClone<T> {
    /* snip */
}

相关问题 rust-lang/rust#62581 “循环计算超特征”错误可能更有帮助 #62581


推荐阅读