Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

6.4 简单的控制流-if let

6.4.1. 什么是if let

if let语法允许把iflet组合成一种更简洁的方式,用来处理只匹配一种模式的值,同时忽略其余模式

可以把if let看作是match的语法糖,也就是只针对某一种特定模式来编写代码。

6.4.2. if let的实际应用

举个例子:v是一个u8变量。判断v是否为0,如果是就打印zero

use rand::Rng;  // 使用外部 crate
fn main(){
    let v: u8 = rand::thread_rng().gen_range(0..=255);  // 生成随机数
    println!("{}", v);
    match v {
        0 => println!("zero"),
        _ => (),
    }
}

这里只需要区分0和非0。在这种情况下,使用if let会更简单:

use rand::Rng;  // 使用外部 crate
fn main(){
    let v: u8 = rand::thread_rng().gen_range(0..=255);  // 生成随机数
    println!("{}", v);
    if let 0 = v {
        println!("zero");
    };
}

注意:if let用的是=而不是==

小改一下上面的例子:v是一个u8变量。判断v是否为0;如果是就打印zero,否则打印not zero

use rand::Rng;  // 使用外部 crate
fn main(){
    let v: u8 = rand::thread_rng().gen_range(0..=255);  // 生成随机数
    println!("{}", v);
    match v {
        0 => println!("zero"),
        _ => println!("not zero"),
    }
}

这种情况下,只需要给if let加上else分支即可:

use rand::Rng;  // 使用外部 crate
fn main(){
    let v: u8 = rand::thread_rng().gen_range(0..=255);  // 生成随机数
    println!("{}", v);
    if let 0 = v {
        println!("zero");
    } else {
	    println!("not zero");
    }
}

6.4.3. 使用if let的取舍

match相比,if let代码更少、缩进更少、模板代码也更少。但if let放弃了穷尽性。

所以,使用if let还是match要根据实际需求来决定。这里存在简洁性与穷尽性之间的取舍

6.4.4. if letif的区别

很多初学者搞不清if letif的区别,因为好像if let能做的,if也能做。但它们本质上不同:if let是模式匹配,而if是条件语句。

if后面的条件只能是布尔值,而if let是匹配是否符合某个具体模式,适合从枚举、OptionResult或其他支持模式匹配的类型中提取值。

例如:

fn main(){
	let x = Some(5);
	if let Some(value) = x {
	    println!("Found a value: {}", value);
	} else {
	    println!("No value found");
	}
}

if无法解包Option。要实现这样的效果,必须使用模式匹配(matchif let)。