如何实现参数化特征的特征

che*_*eme 8 traits rust

我有一个设计问题,当使用类似的东西时:

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

impl<K: OtherTrait, M: MyTrait<K>> AnyTrait for M { ... }
Run Code Online (Sandbox Code Playgroud)

由于E207错误("类型参数K不受impl trait,self type或谓词"约束),我无法为此特征实现特征.

找不到摆脱这个错误,我应用这个不那么好看的解决方法(详细和结构没有内在价值):

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() { }
Run Code Online (Sandbox Code Playgroud)

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

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

Chr*_*gan 5

这里\xe2\x80\x99是使用关联类型的实现(这意味着每种类型只能实现MyTrait一个K):

\n\n
use std::fmt;\n\npub trait MyTrait {\n    type K: fmt::Display;\n    fn get_some_k(&self) -> Option<Self::K>;\n}\n\nimpl<S: MyTrait> fmt::Display for S {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, "{}", self.get_some_k().unwrap())\n    }\n}\n\nfn main() { }\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,当这样澄清时,很明显这种方法也不会起作用,因为你正在Display为所有实现MyTrait\xe2\x80\x94 类型的类型实现,这些类型可能有自己的Display实现。这是禁止的,所以你会得到 E0210:

\n\n
\n

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

\n
\n\n

将其包装在 \xe2\x80\x94 中,就像你Ugly所做的 \xe2\x80\x94 一样,是允许这种实现的唯一方法。或者在您自己的板条箱中实现一项特征,而不是在其他人\xe2\x80\x99s 中实现一项特征(就像Display这样)。

\n