VueBloghyhero6

Rust 知识学习总结

2024-05-31 / 2024-05-31 / 1034次浏览

match 配合 if 进行条件判断,如果判断正确是不会进入到下一个if的

fn main() {
    let number: u8 = 4;

    match number {
        i if i == 0 => println!("Zero"),
        i if i > 0 => println!("Greater than zero"),
        // _ => unreachable!("Should never happen."),
        // TODO ^ uncomment to fix compilation
    }
}

这句话的意思是在 Rust 中,当编译器检查匹配表达式是否覆盖了所有可能的模式时,它不会考虑保护条件(guard conditions)。

在 match 表达式中,可以使用 if 关键字加上一个条件来对某个模式进行保护。如果保护条件为真,则对应的分支会执行;否则,程序会继续匹配下一个模式。然而,在检查是否覆盖了所有可能的模式时,编译器不会考虑这些保护条件,而是只关注模式本身是否已经覆盖了所有情况。

在代码中的注释部分 _ => unreachable!("Should never happen.") 中的 _ 表示一个通配符模式,用来匹配除了之前列出的模式之外的所有情况。通过 unreachable! 宏来标记这种情况应该永远不会发生,因为前面的模式已经覆盖了所有可能的情况。如果取消注释这行代码,就会修复编译错误,因为这样就覆盖了所有可能的情况。

这个match 配合 if 混合使用的情况倒是第一次见 只能说是语言特性

n @ 13 ..= 19 表示匹配的值在范围 13 到 19(包括 13 和 19)之间,并将该值绑定到变量 n 上。

match 匹配是rust 强大的语言机制,

Some(42)

Some(42):

Some(42) 是一个 Option 类型的值,表示一个包含具体值 42 的 Some 变体。
Some 是一个枚举类型,用于表示可能存在值的情况,而 42 则是这个 Some 变体中包含的具体值。

函数又具体分为关联函数和实例函数,具体的一些行为就是,都是定义在 impl 块里面的函数,但是 有的是实例上定义的函数,有的是它称之为关联函数。

比如说下面俩个代码就是关联函数:

struct Point {
    x: f64,
    y: f64,
}

// Implementation block, all `Point` associated functions & methods go in here
impl Point {
    // This is an "associated function" because this function is associated with
    // a particular type, that is, Point.
    //
    // Associated functions don't need to be called with an instance.
    // These functions are generally used like constructors.
    fn origin() -> Point {
        Point { x: 0.0, y: 0.0 }
    }

    // Another associated function, taking two arguments:
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    }
}

区分关联函数和实例函数的主要分别就是,实例方法是依赖于特定实例的函数,可以访问和修改调用对象数据,而关联函数则不依赖于特定实例,与类型本身相关。所以下面这个例子就算比较有实例化,

struct Rectangle {
    p1: Point,
    p2: Point,
}

impl Rectangle {
    // This is a method
    // `&self` is sugar for `self: &Self`, where `Self` is the type of the
    // caller object. In this case `Self` = `Rectangle`
    fn area(&self) -> f64 {
        // `self` gives access to the struct fields via the dot operator
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        // `abs` is a `f64` method that returns the absolute value of the
        // caller
        ((x1 - x2) * (y1 - y2)).abs()
    }

    fn perimeter(&self) -> f64 {
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
    }

    // This method requires the caller object to be mutable
    // `&mut self` desugars to `self: &mut Self`
    fn translate(&mut self, x: f64, y: f64) {
        self.p1.x += x;
        self.p2.x += x;

        self.p1.y += y;
        self.p2.y += y;
    }
}

在上面提供的代码中,area() 和 perimeter() 方法都是实例方法,因为它们没有self参数,而是通过&self参数来访问调用对象的数据

而 translate() 方法是一个实例方法,因为它带有&mut self 参数,表示需要对调用对象进行修改,并且可以访问和修改调用对象的数据。

let one = || 1; 这个就是一个返回1 的闭包。
其实这种写法很省略就像JS 里面的匿名函数一样的难以理解

let mut one = |x: &mut i32| { *x = 1 };

其实这样写也是一个闭包赋值,但是代码量就比较高。闭包这块理解起来是可以单独出一篇文章的。