跳到主要内容

函数

  1. 函数定义:使用fn关键字定义函数,函数名后跟一对圆括号和函数体。
  2. 函数参数:函数可以接收一个或多个参数,参数类型需要显式指定。
  3. 返回值:函数可以返回一个值,返回类型需要显式指定。Rust中的函数使用箭头->来指示返回类型。
  4. 表达式和语句:函数体中的最后一个表达式将作为返回值返回,末尾不需要分号。

定义

基本函数定义

fn main() {
println!("Hello, world!");
}

带参数的函数

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

fn main() {
greet("Alice");
}

带返回值的函数

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

fn main() {
let result = add(5, 3);
println!("The sum is: {}", result);
}

表达式和语句

fn add_one(x: i32) -> i32 {
x + 1 // 末尾不需要分号
}

fn main() {
let result = add_one(5);
println!("Result: {}", result);
}

高阶函数和闭包

1. 高阶函数

高阶函数是可以接收其他函数作为参数或返回其他函数的函数。

fn apply_to_3(f: fn(i32) -> i32) -> i32 {
f(3)
}

fn add_one(x: i32) -> i32 {
x + 1
}

fn main() {
let result = apply_to_3(add_one);
println!("Result: {}", result); // 输出: Result: 4
}

2.闭包

闭包是可以捕获其环境的匿名函数。

fn main() {
let add_one = |x: i32| -> i32 { x + 1 };
let result = add_one(5);
println!("Result: {}", result); // 输出: Result: 6
}

函数的泛型

函数可以使用泛型来处理不同类型的参数

fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}

fn main() {
let numbers = vec![34, 50, 25, 100, 65];
let result = largest(&numbers);
println!("The largest number is {}", result); // 输出: The largest number is 100
}

发散函数

什么是发散函数?

发散函数是那些不会返回到调用者的函数。调用这些函数后,程序不会继续执行调用它们之后的代码。发散函数的返回类型用 ! 表示,读作 "never"。

  • 返回类型是 !:表示这个函数永远不会返回任何值。
  • 改变控制流:调用发散函数后,程序不会继续执行调用它之后的代码。

为什么需要发散函数?

  1. 无限循环:有时我们需要让程序一直运行下去。
  2. 程序中止:当程序遇到无法解决的错误时,停止运行。

发散函数的例子

无限循环

fn infinite_loop() -> ! {
loop {
// 这个循环永远不会停止
}
}

这个函数中的循环永远不会停止,所以这个函数永远不会返回。

程序中止

fn stop_program() -> ! {
panic!("程序遇到严重错误,停止运行!");
}

这个函数会让程序立即停止运行,并显示错误信息。

发散函数的用途

  1. 处理不可恢复的错误:当程序遇到无法继续运行的错误时,可以使用发散函数中止程序。
  2. 保持程序运行:在某些情况下,我们希望程序一直运行,例如一个服务器程序可以包含无限循环以不断处理请求。

示例代码

假设我们有一个函数,需要根据条件决定要么返回一个整数,要么停止程序:

fn get_number(condition: bool) -> i32 {
if condition {
42 // 如果条件为真,返回数字 42
} else {
stop_program() // 如果条件为假,停止程序
}
}

在这个示例中,如果 conditiontrue,函数会返回 42。如果 conditionfalse,函数会调用 stop_program,这会中止程序运行。

总结

发散函数在 Rust 中是一种特殊的函数,它们永远不会返回到调用者。它们可以用于创建无限循环或在遇到严重错误时中止程序。理解和使用发散函数可以帮助我们编写更健壮的程序。

const fn

介绍

const fn 是一种可以在编译时计算结果的函数。它的结果可以用于常量上下文,例如常量表达式、静态变量初始化等。这意味着在编译时就能确定函数的返回值,从而提升程序的性能和安全性。

  • 编译时计算:在编译时就计算结果,可以减少运行时的计算量,提高性能。
  • 常量表达式:在常量上下文中使用,保证常量的初始化在编译时完成,避免运行时错误

const fn 的例子

简单的加法函数

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

const RESULT: i32 = add(5, 3); // 在编译时计算结果

在这个例子中,add 是一个 const fn,它在编译时就计算出结果 8 并赋值给 RESULT

复杂一点的函数

const fn factorial(n: u32) -> u32 {
let mut result = 1;
let mut i = 1;
while i <= n {
result *= i;
i += 1;
}
result
}

const FACTORIAL_5: u32 = factorial(5); // 在编译时计算 5 的阶乘

在这个例子中,factorial 是一个 const fn,计算一个数的阶乘,并在编译时计算 5! 的结果。

const fn 的限制

  1. 限定操作:在 const fn 中,只能使用有限的操作和语法,如算术操作、逻辑操作、条件判断等。不能使用诸如动态分配、I/O 操作等。
  2. 返回值类型:返回值必须是可以在编译时确定的类型。

总结

  • 定义const fn 是在编译时计算结果的函数。
  • 用途:用于提升性能和安全性,确保常量在编译时初始化。
  • 示例:定义简单的加法函数和阶乘函数,并在编译时计算结果。

注释

行注释(line comments)和文档注释(doc comments)。

行注释(line comments)

行注释以 // 开头,Rust编译器会忽略这些注释内容。行注释通常用于解释代码逻辑、标记重要的代码片段或暂时注释掉代码。

fn main() {
// 这是一个行注释
let x = 5; // 变量 x 的声明和赋值
// 以下是一个简单的打印语句
println!("The value of x is: {}", x);
}

文档注释(Doc Comments)

文档注释以 /// 开头,通常放在函数、结构体、枚举等之前,用于生成文档。使用 cargo doc 命令可以生成HTML格式的文档。文档注释支持Markdown语法。

/// 这是一个计算两个数之和的函数。
///
/// # 参数
///
/// * `a` - 第一个数
/// * `b` - 第二个数
///
/// # 返回值
///
/// 返回两个数的和。
fn add(a: i32, b: i32) -> i32 {
a + b
}

fn main() {
let result = add(5, 3);
println!("5 + 3 = {}", result);
}

通途

行注释用于注释代码,而文档注释用于生成文档。