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 };
其实这样写也是一个闭包赋值,但是代码量就比较高。闭包这块理解起来是可以单独出一篇文章的。
文章采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接。