【问题标题】:How can I reuse code for similar trait implementations?如何为类似的 trait 实现重用代码?
【发布时间】:2015-09-06 06:49:28
【问题描述】:

我有一些需要相同方法的默认实现的特征,这些方法恰好是字段获取器。

trait AddPosition<T: Display>{
    fn x(&self) -> T;
    fn y(&self) -> T;
    fn add(&self){
        println!("{:}", self.x()+self.x());
    }
}

trait SubPosition<T: Display>{
    fn x(&self) -> T;
    fn y(&self) -> T;
    fn sub(&self){
        println!("{:}", self.x()-self.y());
    }
}

我可以有这样的东西,而不是为每个特征实现手动重复相同的代码吗?

impl AddPosition<i32>, SubPosition<i32> for Point{
    fn x(&self) -> i32{ self.x }
    fn y(&self) -> i32{ self.y }
}

【问题讨论】:

    标签: rust


    【解决方案1】:

    最好的选择可能是考虑到你的对象可以有一个位置的事实:

    trait Position<T: Display> {
        fn x(&self) -> T;
        fn y(&self) -> T;
    }
    
    // trait AAA: BBB --> means AAA must implement BBB
    trait AddPosition<T: Add<Output=T> + Display>: Position<T> {
        fn add(&self){
            println!("{:}", self.x()+self.x()); // ?
        }
    }
    
    trait SubPosition<T: Sub<Output=T> + Display>: Position<T> {
        fn sub(&self){
            println!("{:}", self.x()-self.y()); // ?
        }
    }
    
    struct MyPosition {
        x: i32,
        y: i32,
    }
    
    impl Position<i32> for MyPosition {
        fn x(&self) -> i32 { self.x }
        fn y(&self) -> i32 { self.y }
    }
    impl SubPosition<i32> for MyPosition {}
    impl AddPosition<i32> for MyPosition {}
    

    (Playground)

    但是,我无法理解您的代码如何真正有意义(? 注释行)。如果这只是为了最小的例子,这完全没问题;但是,如果这适用于任何严肃的代码,您可能需要查看AddSub 特征,这将使您受益于运算符重载+-。即使您不直接使用这些特征,它们也可能会启发您对潜在的add(&amp;self, rhs: &amp;P) -&gt; P 函数(其中P: Position&lt;T&gt;)进行有意义的签名。

    【讨论】:

    • 那我应该如何impl AddPosition 和 SubPosition 呢?
    • 查看编辑,其中包括一个实现 AddPosition 和 SubPosition 的结构示例。
    • (另一个 Rustacean 的相邻问题:x 作为字段与 x() 作为方法处理的潜在名称冲突如何?我预计这里会出现编译器错误。)
    • 顺便说一句,Add&lt;Output=T&gt; 输出是什么意思?
    • Add 有一个类型参数 RHS 默认为 Self (所以我不必显式指定它)和一个 associated type Output,它在此处指定结果方法add()。因此,如果我的 X 类型是 Add&lt;RHS=Y, Output=Z&gt;,我将能够调用 (some X) + (some Y),将其脱糖为 (some X).add((some Y)) 并得到一些 Z
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多