【问题标题】:How to implement a trait for a parameterized trait如何为参数化特征实现特征
【发布时间】:2015-08-07 01:27:05
【问题描述】:

我在使用类似的东西时遇到了设计问题:

trait MyTrait<K: OtherTrait> { ... }

impl<K: OtherTrait, M: MyTrait<K>> AnyTrait for M { ... }

由于 E207 错误,我无法为此 trait 实现 trait(“类型参数 K 不受 impl trait、self 类型或谓词的约束”)。

找不到摆脱这个错误的方法,我申请了this not-so-good-looking workaround(详细和没有内在价值的结构):

use std::fmt;
use std::marker::PhantomData;

pub trait MyTrait<K: fmt::Display> {
    fn get_some_k(&self) -> Option<K>;
}

/* // This is my target impl but results in E207 due to K not constrained
impl<K: fmt::Display, S: MyTrait<K>> fmt::Display for S {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.get_some_k().unwrap())
    }
} */
pub struct Ugly<'a, K: fmt::Display, S: 'a + MyTrait<K>>(&'a S, PhantomData<K>);
impl<'a, K: fmt::Display, S: MyTrait<K>> fmt::Display for Ugly<'a, K, S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0.get_some_k().unwrap())
    }
}

fn main() { }

我认为应该有一些更好的方法来实现这种参数化特征的特征。

我没有在 std 中找到好的示例(例如,在具有关联类型(如 Iterator)的特征中没有实现 Display)?

【问题讨论】:

  • 只是想我会提到我遇到了完全相同的问题,但是我没有将毯子 impl 包裹在 Ugly 中的奢侈,因为 MyTrait 是公开的向用户公开的 trait 并要求他们使用 Ugly 通过增加不必要的复杂性彻底破坏 API。

标签: rust traits


【解决方案1】:

Here’s an implementation using associated types(这意味着您只能为每个类型实现一个MyTrait K):

use std::fmt;

pub trait MyTrait {
    type K: fmt::Display;
    fn get_some_k(&self) -> Option<Self::K>;
}

impl<S: MyTrait> fmt::Display for S {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.get_some_k().unwrap())
    }
}

fn main() { }

但是,当这样澄清时,很明显这种方法也行不通,因为您正在为所有实现 MyTrait 的类型实现 Display——这些类型可能有自己的 Display 实现。这是禁止的,所以你得到 E0210:

错误:类型参数S必须用作某些本地类型的类型参数(例如MyStruct&lt;T&gt;);类型参数只能实现当前 crate 中定义的特征 [E0210]

将它包装在一些东西中——就像你的Ugly 所做的那样——是允许这种实现的唯一方法。或者在你自己的 crate 中实现一个 trait,而不是在其他人的 crate 中实现(比如 Display 是)。

【讨论】:

  • 谢谢,我考虑过关联类型,但我的情况是每种类型需要多个实现,否则它会完成工作(我的用例不是Display)。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2018-04-11
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多