1016 字
约 3 分钟
0
控制流

控制流

所谓控制流, 就是控制程序的流程。

在没有控制流的情况下, 程序会按顺序从上往下逐行执行。 而控制流语句可以让我们根据条件选择性地执行某段代码, 或者重复执行某段代码, 从而让程序拥有判断和循环的能力。

if/else 分支

if/else 是 Rust 中最常用的控制流语句。

它用于判断某个条件是否成立。 它的判断条件必须返回布尔值, 而不是其他类型。

如果判断条件成立, 则执行 if 后面的代码块。 如果判断条件不成立, 则执行 else 后面的代码块。

  let mut content = String::from("default content");

  if len > 2{
    content = args[2].clone();
  }

当参数格式多于两个时, 取第三个参数替换变量 content 的值。 否则 content 不变。

需要注意的是, Rust 中的 if 是一个表达式。允许有返回值。因此以上代码可以改为:

  let content = if len > 2 {
    args[2].clone()
  } else {
    String::from("default content")
  };

以上代码意思是, 如果 len > 2 条件成立, 就使用 args[2].clone() 作为 content 的值。 否则, 就使用 String::from("default content") 作为 content 的值。

Rust 是一种表达式导向的语言, 实际上大部分的结构都可以返回值。

循环

Rust 中, 循环方式如下:

  • loop 循环会一直执行, 直到遇到 break 语句。
  • while 循环会在条件成立的情况下执行。
  • for 循环会遍历一个集合中的所有元素。

我们将使用 while 实现一个交互式的命令行输入, 逐步获取 Todo 的标题与内容, 并确认是否创建该条 Todo。

修改 main.rs 代码如下:

fn main() {
  let mut inputs: Vec<String> = Vec::new();
  let args: Vec<String> = std::env::args().collect();
  let mut ok = args[1].clone() == "create";

  while ok {
    let len = inputs.len();

    if len == 0 {
      println!("Please input todo title");

      let mut title = String::new();

      std::io::stdin()
        .read_line(&mut title)
        .expect("read line failed");

      if title.is_empty() {
        continue;
      }

      inputs.push(title.trim().to_string());

    } else if len == 1 {
      println!("Please input todo content");

      let mut content = String::new();

      std::io::stdin()
        .read_line(&mut content)
        .expect("read line failed");

      if content.is_empty() {
        continue;
      }

      inputs.push(content.trim().to_string());
    }

    else {
      println!("title:   [{}]", inputs[0].clone());
      println!("content: [{}]", inputs[1].clone());
      println!("Are you sure to create this todo? (y/n)");

      let mut sure = String::new();

      std::io::stdin()
        .read_line(&mut sure)
        .expect("read line failed");

      if sure.trim().to_lowercase() != "n" {
        ok = false;
      }else{
        inputs.clear();
      }
    }
  }

  let title = inputs[0].clone();
  let content = inputs[1].clone();

  println!("create todo title: {}, content: {}", title, content);
}

以上代码中, 我们使用了 while 循环来实现一个交互式, 用于创建 Todo 项的命令行程序。

我们使用了一个状态变量 ok 来控制循环, 当 okfalse 时, 循环会结束。 并在用户输入的内容为空时, 使用 continue 语句来跳过当前循环。

如果改成 loop 循环的话如下所示:

loop {
  // 其他地方保持不变

  if sure.trim().to_lowercase() != "n" {
    ok = false;
  }else{
    inputs.clear();
  }

  if !ok {
    break
  }
}

whileloop 都可以用来循环, 效果可以说是等价的。

两者区别在于:

  • while 适合用于条件驱动的循环, 比如获取用户输入并确认。
  • loop 则更适合结构复杂, 需要手动控制循环的情况。例如游戏开发。

现在, 执行 cargo run -- create 就可以进入交互式界面来创建 Todo 项了。

for 循环

for 循环常用于遍历一个数据集合。

我们将为 CLI 程序增加一个 list 命令, 用于列出所有的 Todo 项。

修改 main.rs 如下:

fn main() {
  let mut todos: Vec<String> = Vec::new();
  todos.push(String::from("learn rust"));
  todos.push(String::from("work"));
  todos.push(String::from("play"));

  let args: Vec<String> = std::env::args().collect();
  let mut inputs: Vec<String> = Vec::new();

  if args[1].clone() == "list" {
    for todo in todos {
      println!("todo title: {}", todo);
    }
    return;
  }

  let mut ok = args[1].clone() == "create";

  // ...
}

相较于需要手动管理索引的 whileloop, for 可以更简洁安全的遍历数据集合。 是 Rust 中处理数据集合的首选方式。

控制流
http://www.clxhxhhr.top/posts/442/
作者
clxstart
发布于
2026-09-04
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。
文章目录