Please enable Javascript to view the contents

[Rust Std Trait] std::ops 初见

 ·  ☕ 1 分钟

前言

    由于 ops 中的很多 trait 功能类似,所以就不一个一个来了。本篇文章以最短的篇幅概括 std::ops 中还未提及的主要知识点。

运算符重载

    最基础的就是对四则运算之类的操作符进行重载了。这里借用计算点坐标的例子来演示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
extern crate hello_rust;
use std::ops::Add;

#[derive(Debug, Clone, Copy)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Self;

    fn add(self, rhs: Point) -> Self {
        Self {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    println!("{:?}", Point { x: 1, y: 2 } + Point { x: 2, y: 1 });
}

FnOnce/FnMut/Fn

    Rust 中用 fn 可以定义函数,而 Fn 可以对函数做抽象。三种不同形态对应 self 参数的传递类型。FnOnce 对应 move 传递,这样的函数不能执行多次,所以签名带了个 Once。FnMut/Fn 分别对应 &mut Self 和 &Self 类型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
pub trait FnOnce<Args> {
    type Output;
    pub extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

pub trait FnMut<Args>: FnOnce<Args> {
    pub extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

pub trait Fn<Args>: FnMut<Args> {
    pub extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

let x = String::from("x");
let consume_and_return_x = move || x; // FnOnce() -> String

let mut square_x = || x *= x; // FnMut()

let double = |x| x * 2; // Fn()

编译器在自动为闭包实现 trait 的时候会先试 Fn 不行再 FnMut 最后 FnOnce。

文档中特别提到如果 F 实现了 Fn 那么自动 &F 也实现了 Fn。这句话我们可以利用下面的例子来感受一下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
extern crate hello_rust;

fn test_fn<T>(f: &T)
where
    T: Fn(),
{
    f();
}

fn main() {
    let a = || println!("hello world");
    test_fn(&a);
}

Range 语法

    Range 语法总共六种形态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
extern crate hello_rust;

fn main() {
    let arr = [0, 1, 2, 3];

    assert_eq!([0, 1, 2, 3], arr[..]);
    assert_eq!([1, 2, 3], arr[1..]);
    assert_eq!([0, 1], arr[..2]);
    assert_eq!([0, 1, 2], arr[..=2]);
    assert_eq!([1], arr[1..2]);
    assert_eq!([1, 2], arr[1..=2]);
}
分享

saberuster
作者
saberuster
一个喜欢编程和折腾的追风少年