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

  • Louis
  • 更新于 2024-06-25 16:10
  • 阅读 555

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

函数的基本概念

在 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: &stra: 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)、循环(loopwhilefor)和匹配(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 ifelse 来处理多重条件。
  • 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 标准库中提供的一个类型,它生成从一个开始值到一个结束值(但不包括结束值)的序列。

使用 Rangefor 循环

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);
    }
}

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

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 结构允许将一个值与一系列模式进行比较,执行匹配的代码块。
  • 每个分支由一个模式和一个代码块组成,模式和代码块之间使用 => 分隔。
  • _ 模式是通配符,匹配所有未匹配的情况。
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Louis
Louis
web3 developer,技术交流或者有工作机会可加VX: magicalLouis