从带标签的循环返回一个值

Amr*_*ama 4 control-flow rust

我们可以使用 循环返回一个值break,例如:

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {result}");
}

Run Code Online (Sandbox Code Playgroud)

我们可以使用标签来中断外循环,但是有没有办法在中断外循环的同时返回一个值?

fn main() {
    let mut count = 0;
    'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;

        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up; // <-- Want to retun a value here
            }
            remaining -= 1;
        }

        count += 1;
    }
    println!("End count = {count}");
}

Run Code Online (Sandbox Code Playgroud)

use*_*968 7

Rust 中的循环是表达式,虽然大多数循环的计算结果为(),但您可以break使用一个值,包括中断到外部标签。在下面的示例中,这是通过break 'counting_up Some(1)分配循环的值来完成的let foo: Option<usize> = 'counting_up: loop {

请注意,编译器将强制所有控制流路径计算为相同类型(即 的类型foo)。如果您的循环并非在所有情况下都产生值,您可以简单地使用Option,如下例所示。

fn main() {
    let mut count = 0;

    // Assign the loop's value to `foo`
    let foo: Option<usize> = 'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;

        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                // Value found
                break 'counting_up Some(1);
            }
            if count == 3 {
                // Break early, assign `None` to `foo`
                break 'counting_up None;
            }
            remaining -= 1;
        }

        count += 1;

        if count >= 42 {
            // break from 'counting_loop, assign `None` to `foo`
            break None;
        }
    };

    println!("End count = {foo:?}");
}
Run Code Online (Sandbox Code Playgroud)