Sitelet https://github.com/MagicalBridge/Blog/issues/74
Skip to content

Rust入门系列:08、Rust中的函数和控制流 #74

Description

@MagicalBridge

函数的基本概念

在 Rust 中,函数是通过 fn 关键字来定义的。函数定义包括函数名、参数、返回类型(如果有)、和函数体。函数的参数需要明确指定类型,Rust 的函数参数和返回类型通常使用静态类型检查。

示例代码

fn main() {
    greet("Alice");
    let sum = add(5, 3);
    println!("Sum is: {}", sum);
}

fn greet(name: &str) {
    println!("Hello, {}!", name);
}

fn add(a: i32, b: i32) -> i32 {
    a + b
}

代码解释

  1. 函数定义:

    • 使用 fn 关键字。
    • 函数名后跟一对圆括号,括号内可以包含参数列表。
    • 参数需要指定类型,参数名和类型之间使用冒号分隔。
    • 函数体包含在花括号 {} 中。
  2. 参数:

    • 参数类型必须显式声明,如 name: &str、a: i32。
    • 参数列表中的每个参数之间用逗号分隔。
  3. 返回类型:

    • 返回类型通过箭头 -> 指定,紧跟在参数列表之后。
    • 如果函数没有返回值,可以省略返回类型,或者显式地返回一个空元组 ()。
    • 最后一条表达式的值就是返回值,无需使用 return 关键字,但可以显式使用 return 关键字。
  4. 函数调用:

    • 函数通过函数名和参数列表调用,如 greet("Alice")、add(5, 3)。
  5. 注意事项:

    • Rust 函数默认是私有的,如果需要在模块外部使用,需要使用 pub 关键字将其声明为公共函数。
    • 参数传递是按值传递,除非使用引用 & 或可变引用 &mut。

带有可变参数的函数

fn main() {
    let mut x = 5;
    change_value(&mut x);
    println!("Changed value: {}", x);
}

fn change_value(val: &mut i32) {
    *val = 10;
}

带有可选参数的函数

Rust 本身不支持像 Python 那样的默认参数,但是可以使用 Option 类型来模拟:

fn main() {
    print_number(Some(10));
    print_number(None);
}

fn print_number(number: Option<i32>) {
    match number {
        Some(n) => println!("Number is: {}", n),
        None => println!("No number provided"),
    }
}

Rust中的控制流

在 Rust 中,控制流结构包括条件判断(if)、循环(loop、while、for)和匹配(match)。这些结构用于控制程序的执行流程。

1. 条件判断(if)

fn main() {
    let number = 5;

    if number < 10 {
        println!("The number is less than 10");
    } else {
        println!("The number is 10 or greater");
    }

    // if-else if-else 结构
    let condition = true;
    let value = if condition { 1 } else { 0 };
    println!("The value is: {}", value);
}

代码解释

  • if 语句用于条件判断,条件表达式必须返回一个布尔值(bool)。
  • 可以使用 else if 和 else 来处理多重条件。
  • if 表达式可以有返回值,并且所有分支必须返回相同类型的值。

2. 循环(loop, while, for)

无限循环(loop)

fn main() {
    let mut count = 0;

    loop {
        count += 1;
        if count == 3 {
            println!("Loop exited");
            break;
        }
    }
}

条件循环(while)

fn main() {
    let mut number = 3;

    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
    println!("Liftoff!");
}

迭代循环(for)

fn main() {
    let array = [10, 20, 30, 40, 50];

    for element in array.iter() {
        println!("The value is: {}", element);
    }

    for number in 1..4 {
        println!("{}!", number);
    }
    println!("Liftoff!");
}

解释

  • loop 创建一个无限循环,可以使用 break 关键字退出循环。
  • while 循环在条件为 true 时反复执行。
  • for 循环用于遍历集合或范围,1..4 生成从 1 到 3 的序列,array.iter() 迭代数组的每个元素。

Rust 中的 for 循环可以配合 Range 使用,方便地遍历一系列连续的值。Range 是 Rust 标准库中提供的一个类型,它生成从一个开始值到一个结束值(但不包括结束值)的序列。

使用 Range 的 for 循环

fn main() {
    // 使用 Range 遍历从 1 到 4 的值(不包含 4)
    for i in 1..4 {
        println!("The value is: {}", i);
    }

    // 使用 Range 遍历从 1 到 4 的值(包含 4)
    for i in 1..=4 {
        println!("The value is: {}", i);
    }

    // 反向遍历从 4 到 1 的值(包含 4)
    for i in (1..=4).rev() {
        println!("The value is: {}", i);
    }
}

解释

  1. 1..4:

    • 生成一个从 1 到 3 的范围(1, 2, 3),不包括 4。
    • 这是一个半开区间(start..end)。
  2. 1..=4:

    • 生成一个从 1 到 4 的范围(1, 2, 3, 4),包括 4。
    • 这是一个闭区间(start..=end)。
  3. .rev():

    • 使用 rev() 方法反转范围内的顺序。
    • 例如 (1..=4).rev() 会生成 4, 3, 2, 1。

特点和注意事项

  • 简洁性:使用 Range 可以简洁地创建循环范围,避免手动设置和更新循环变量。
  • 边界:注意 Range 是左闭右开区间(start 包含,end 不包含),使用 ..= 可以创建闭区间。
  • 类型推断:Rust 能够根据上下文推断 Range 的类型,但在某些情况下可能需要显式指定类型。
  • 安全性:Range 确保索引不越界,避免了手动设置循环变量时可能出现的错误。

遍历数组或向量

fn main() {
    let array = [10, 20, 30, 40, 50];

    for i in 0..array.len() {
        println!("The value at index {} is: {}", i, array[i]);
    }

    let vector = vec![1, 2, 3, 4, 5];
    for i in 0..vector.len() {
        println!("The value at index {} is: {}", i, vector[i]);
    }
}

遍历字符范围

fn main() {
    for c in 'a'..='e' {
        println!("The character is: {}", c);
    }
}

使用 Range 的 for 循环使得遍历数值范围、数组、向量和字符范围变得直观且高效。

3. 匹配(match)

fn main() {
    let number = 3;

    match number {
        1 => println!("One"),
        2 => println!("Two"),
        3 => println!("Three"),
        _ => println!("Something else"),
    }

    let result = match number {
        1 => "One",
        2 => "Two",
        3 => "Three",
        _ => "Other",
    };
    println!("Result is: {}", result);
}

解释

  • match 结构允许将一个值与一系列模式进行比较,执行匹配的代码块。
  • 每个分支由一个模式和一个代码块组成,模式和代码块之间使用 => 分隔。
  • _ 模式是通配符,匹配所有未匹配的情况。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions