Rust - 函数
Rust - 函数
Section titled “Rust - 函数”函数是 Rust 程序的基本构建块。它们封装了特定的任务,使代码可重用、可读且易于维护。函数将程序组织成逻辑上自包含的单元。
定义和调用函数
Section titled “定义和调用函数”在 Rust 中,你使用 fn 关键字定义函数,后跟函数名、用于参数的圆括号 () 和用于函数体的花括号 {}。函数名通常使用 snake_case 命名约定。
// `main` 函数是每个 Rust 可执行文件的入口点。fn main() { println!("Hello from main function!");
// 调用另一个函数 another_function();}
// 定义另一个函数fn another_function() { println!("Hello from another function!");}Hello from main function!Hello from another function!函数可以接受称为**参数(parameters)**的输入。在函数签名中,你必须声明每个参数的名称和类型。这允许你将值传递给函数进行处理。
fn main() { print_value(10); print_sum(5, 6);}
// 一个带有一个 i32 类型参数的函数fn print_value(x: i32) { println!("The value is: {}", x);}
// 一个带有两个参数的函数fn print_sum(x: i32, y: i32) { println!("The sum is: {}", x + y);}语句 vs. 表达式和返回值
Section titled “语句 vs. 表达式和返回值”Rust 函数体由一系列语句组成,最后可以是一个可选的表达式。**语句(Statements)**是执行操作但不返回值(例如 let y = 6;)的指令。**表达式(Expressions)**会求值并产生一个结果值(例如 5 + 6)。
函数可以将值返回给调用它的代码。返回类型在箭头 -> 后面声明。返回的值是函数体中最后一个表达式的值。你也可以使用 return 关键字来提前从函数返回。
fn main() { let sum = add_five(10); println!("10 + 5 = {}", sum);
let product = multiply(8, 7); println!("8 * 7 = {}", product);}
// 此函数返回一个 i32。// `x + 5` 这一行是一个表达式,因为它在最后一行,// 其值会自动返回。fn add_five(x: i32) -> i32 { x + 5 // 这里没有分号!}
// 这个函数也返回一个 i32,但使用了 `return` 关键字。fn multiply(x: i32, y: i32) -> i32 { return x * y; // 这里的 `;` 是可选的,但建议保留。}10 + 5 = 158 * 7 = 56传递参数:所有权 vs. 借用
Section titled “传递参数:所有权 vs. 借用”你向函数传递参数的方式直接与 Rust 的所有权系统交互。与其思考“按值传递(pass-by-value)”和“按引用传递(pass-by-reference)”,不如更准确地将其理解为移动所有权或借用。
1. 按值传递(移动)
Section titled “1. 按值传递(移动)”当你将变量传递给函数时,数据的所有权会**移动(moved)**到函数的参数中。原始变量将不能再使用。这适用于未实现 Copy trait 的类型,例如 String 或 Vec<T>。
fn main() { let s = String::from("hello"); takes_ownership(s);
// 下面这行代码将无法编译,因为 `s` 的值已被移动。 // println!("{}", s);}
fn takes_ownership(some_string: String) { println!("I now own the string: {}", some_string);} // `some_string` 在此处被丢弃,其内存被释放。2. 按引用传递(借用)
Section titled “2. 按引用传递(借用)”要在不获取所有权的情况下使用值,你可以传递一个引用(reference)。这被称为借用(borrowing)。调用者保留所有权。引用默认是不可变的。
fn main() { let s1 = String::from("hello");
// 传递字符串的不可变引用。 let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len); // `s1` 仍然有效,可以在这里使用。}
// 此函数借用 String 而不是获取所有权。fn calculate_length(s: &String) -> usize { s.len()} // `s` 超出作用域,但它引用的数据不会被丢弃。3. 传递可变引用(可变借用)
Section titled “3. 传递可变引用(可变借用)”如果你需要修改借用的值,你可以使用 &mut 传递一个可变引用(mutable reference)。在特定作用域内,你只能拥有一个对特定数据的可变引用。
fn main() { let mut s = String::from("hello"); println!("Original string: {}", s);
// 传递一个可变引用。 change(&mut s);
println!("Modified string: {}", s);}
fn change(some_string: &mut String) { some_string.push_str(", world");}Original string: helloModified string: hello, world