Rust特征及其默认实现

时间:2018-06-10 18:35:15

标签: traits

写了一个检查给定数字(u16或u32)是否均匀的特征。

1.0

trait EvenOdd {
    fn is_even(&self) -> bool;
}

impl EvenOdd for u16 {
    fn is_even(&self) -> bool {
        self % 2 == 0
    }
}

impl EvenOdd for u32 {
    fn is_even(&self) -> bool {
        self % 2 == 0
    }
}

fn main() {
    let x: u16 = 11;
    let y: u32 = 44;

    println!("x = {}, y = {}", x.is_even(), y.is_even());
}

这很好。但是,由于is_evenu16重复u32,因此将其作为默认方法移至特征中。

2.0

trait EvenOdd {
    fn is_even(&self) -> bool {
        self % 2 == 0
    }
}

impl EvenOdd for u16 {
}

impl EvenOdd for u32 {
}

fn main() {
    let x: u16 = 11;
    let y: u32 = 44;

    println!("x = {}, y = {}", x.is_even(), y.is_even());
}

这会产生编译器错误:

error[E0369]: binary operation `%` cannot be applied to type `&Self`
 --> trait_arithmetic_v2.rs:3:9
  |
3 |         self % 2 == 0
  |         ^^^^^^^^
  |
  = note: an implementation of `std::ops::Rem` might be missing for `&Self`

尝试约束&self会导致编译器错误:

fn is_even<T: std::ops::Rem> (&self: T) -> bool
    self % 2 == 0
}

error: expected one of `)` or `,`, found `:`
 --> trait_arithmetic_v2.rs:2:44
  |
2 |         fn is_even<T: std::ops::Rem> (&self: T) -> bool {
  |                                            ^ expected one of `)` or `,` here

我可以应用约束的唯一方法是更改​​is_even api。

3.0

use std::ops::Rem;

trait EvenOdd {
    fn is_even<T: Rem<Output = T> + PartialEq + From<u8>> (&self, other: T) -> bool {
        other % 2.into() == 0.into()
    }
}

并像x.is_even(x)一样使用它,这是不自然的。如何修复我的v2.0?感谢。

1 个答案:

答案 0 :(得分:0)

v2.0中,编译器不知道您尝试应用算术运算的类型,而trait EvenOdd: Rem不起作用,因为Rem需要{{1} }}

此代码有些限制但适用于您的示例,并且它是有效的,因为有Self的默认实现。

impl From<u16> for u32