算术与比特位操作符 Arithmetic and bitwise operators

标准库里提供的算术与比特位操作符 trait, 都列在了下面表格里:

分类trait表达式描述
一元操作符std::ops::Neg-x取负值
std::ops::Not!x取逻辑否
二元算术操作符std::ops::Addx + y算术相加操作
std::ops::Subx - y算术相减操作
std::ops::Mulx * y算术相乘操作
std::ops::Divx / y算术相除操作
std::ops::Remx % y算术求余操作
二元比特位操作符std::ops::BitAndx & y按位与操作
std::ops::BitOr`xy`
std::ops::BitXorx ^ y按位与或操作
std::ops::Shlx << y左移
std::ops::Shrx >> y右移
二元赋值算术操作符std::ops::AddAssignx += y算术相加
std::ops::SubAssignx -= y算术相减
std::ops::MulAssignx *= y算术相乘
std::ops::DivAssignx /= y算术相除
std::ops::RemAssignx %= y算术求余
二元赋值比特位操作符std::ops::BitAndAssignx &= y按位与赋值
std::Ops::BitOrAssign`x= y`
std::ops::BitXorAssignx ^ y按位与或赋值
std::ops::ShlAssignx <<= y左移赋值
std::ops::ShrAssignx >>= y右移赋值

接下来以复数类型为例, 其定义如下:

#![allow(unused)]
fn main() {
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Complex<T> {
    /// 实数部分
    pub re: T,

    /// 虚数部分
    pub im: T,
}

pub type Complex32 = Complex<f32>;
pub type Complex64 = Complex<f64>;

impl<T> Complex<T> {
    #[must_use]
    #[inline]
    pub const fn new(re: T, im: T) -> Self {
        Self { re, im }
    }
}
}

一元操作符

trait表达式等价的表达式
std::ops::Neg-xx.neg()
std::ops::Not!xx.not()

一元操作符 -, 对应于Neg trait, 它的接口定义如下:

#![allow(unused)]
fn main() {
pub trait Neg {
    type Output;
    fn neg(self) -> Self::Output;
}
}

只需要定义 neg() 方法即可, 我们来复数结构实现这个trait:

#![allow(unused)]
#![allow(clippy::module_name_repetitions)]

fn main() {
use std::ops::{Add, Div, Mul, Neg, Sub};

/// A complex number in Cartesian form.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Complex<T> {
    /// Real part of the complex number.
    pub re: T,

    /// Imaginary part of the complex number.
    pub im: T,
}

pub type Complex32 = Complex<f32>;
pub type Complex64 = Complex<f64>;

impl<T> Complex<T> {
    #[must_use]
    #[inline]
    pub const fn new(re: T, im: T) -> Self {
        Self { re, im }
    }
}

impl<T: Neg<Output = T>> Neg for Complex<T> {
    type Output = Self;

    fn neg(self) -> Self::Output {
        Self {
            re: -self.re,
            im: -self.im,
        }
    }
}
}

逻辑否操作!, 对应于 Not trait, 它的接口定义如下:

#![allow(unused)]
fn main() {
pub trait Not {
    type Output;
    fn not(self) -> Self::Output;
}
}

复数并不需要实现这个操作, 我们用别的例子来展示一下:

#![allow(unused)]
fn main() {
use std::ops::Not;

#[derive(Debug, PartialEq)]
enum Answer {
    Yes,
    No,
}

impl Not for Answer {
    type Output = Self;

    fn not(self) -> Self::Output {
        match self {
            Answer::Yes => Answer::No,
            Answer::No => Answer::Yes
        }
    }
}

assert_eq!(!Answer::Yes, Answer::No);
assert_eq!(!Answer::No, Answer::Yes);
}

二元算术操作符

先来介绍 Add trait, 它定义了加法操作, 其接口如下:

#![allow(unused)]
fn main() {
pub trait Add<Rhs = Self> {
    type Output;

    fn add(self, rhs: Rhs) -> Self::Output;
}
}

下面的例子代码就是为复数实现 Add trait:

impl<T: Add<T, Output=T>> Add for Complex<T> {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self {
            re: self.re + rhs.re,
            im: self.im + rhs.im,
        }
    }
}

其它几个二元算术操作符的定义与上面的类似, 我们一并列出来:

pub trait Sub<Rhs = Self> {
    type Output;
    fn sub(self, rhs: Rhs) -> Self::Output;
}

pub trait Mul<Rhs = Self> {
    type Output;
    fn mul(self, rhs: Rhs) -> Self::Output;
}

pub trait Div<Rhs = Self> {
    type Output;
    fn div(self, rhs: Rhs) -> Self::Output;
}

pub trait Rem<Rhs = Self> {
    type Output;
    fn rem(self, rhs: Rhs) -> Self::Output;
}

为复数实现这些接口:

impl<T: Sub<T, Output=T>> Sub for Complex<T> {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            re: self.re - rhs.re,
            im: self.im - rhs.im,
        }
    }
}

impl<T> Mul for Complex<T>
    where
        T: Copy + Add<T, Output=T> + Sub<T, Output=T> + Mul<T, Output=T>,
{
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        let re = self.re * rhs.re - self.im * rhs.im;
        let im = self.re * rhs.im + self.im * rhs.re;
        Self { re, im }
    }
}

impl<T> Div for Complex<T>
    where
        T: Copy + Add<T, Output=T> + Sub<T, Output=T> + Mul<T, Output=T>,
{
    type Output = Self;

    fn div(self, rhs: Self) -> Self::Output {
        let re = self.re * rhs.re + self.im * rhs.im;
        let im = self.im * rhs.re - self.re * rhs.im;
        Self { re, im }
    }
}

二元比特位操作符

二元赋值算术操作符

二元赋值比特位操作符