» Rust快速入门 » 1. 基础篇 » 1.9 函数

函数

使用 fn 关键字声明函数。Rust 代码给函数和变量使用 snake case 蛇形 命名风格,其所有字母都是小写,并使用下划线分隔单词。

fn factorial(n: u64) -> u64 {
    if n == 0 {
        1
    } else {
        n * factorial(n - 1)
    }
}

fn main() {
    let n = 5;
    let result = factorial(n);
    println!("Factorial of {} is: {}", n, result);
    // 5 的阶乘是: 120
}

方法

有些函数与特定类型相关联。它们有两种形式:关联函数方法

struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // 关联函数,用于创建新的 Rectangle 实例
    fn new(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
}

fn main() {
    // 调用关联函数以创建新的 Rectangle
    let rectangle = Rectangle::new(10, 20);
    println!("Rectangle width: {}", rectangle.width); // Rectangle width: 10
    println!("Rectangle height: {}", rectangle.height); // Rectangle height: 20
}

new(...) 是一个关联函数,因为它与特定类型 Rectangle 相关联。关联函数不需要通过实例调用。

struct Circle {
    radius: f64,
}

impl Circle {
    // 方法,用于计算 Circle 实例的面积
    fn calculate_area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

fn main() {
    let circle = Circle { radius: 5.0 };
    // 调用方法以计算圆的面积
    let area = circle.calculate_area();
    println!("Circle area: {}", area);
    // Circle area: 78.53981633974483
}

calculate_area() 是一个方法,它既是一个关联函数,又必须在特定类型的实例上调用。

闭包

闭包是可以捕获封闭环境的函数。例如,|v| v + x 是一个捕获 x 变量的闭包。 在 Rust 中,闭包使用 || 而不是 () 包围输入变量。对于单表达式闭包,大括号 {} 可省略。

fn main() {
    let outer_var = 58;
    let closure_annotated = |i: i32| -> i32 { i + outer_var };
    let closure_inferred  = |i| i + outer_var  ;
    println!("closure_annotated: {}", closure_annotated(5));
    // closure_annotated: 63
    println!("closure_inferred: {}", closure_inferred(5));
    // closure_inferred: 63
}

当将闭包作为输入参数时,闭包的完整类型必须使用下方的这些 traits 进行注解。

  • Fn: 闭包通过引用(&T)使用捕获的值
  • FnMut: 闭包通过可变引用(&mut T)使用捕获的值
  • FnOnce: 闭包通过值(T)使用捕获的值
fn apply<F>(f: F) where F: FnOnce() {
    // 闭包没有输入并且不返回任何内容。
    f();
}

fn main() {
    let greeting = "hello";
    let c = || {
        println!("I said {}.", greeting);
    };
    apply(c); // I said hello.
}

发散函数

发散函数永远不会返回。它们用 ! 标记,这是一种空类型。

fn bar() -> ! {
    panic!("Something is wrong.")
}

代码挑战

尝试修改编辑器中提供的闭包代码,使其输出 [4, 16, 36, 64, 100].

Loading...
> 此处输出代码运行结果
上页
下页