3.2 函数参数与返回值
在 Rust 中,函数是组织代码的基本单元。理解如何向函数传递数据以及如何从函数返回数据,是编写高效、安全 Rust 程序的关键。本节将深入探讨 Rust 函数的参数传递机制和返回值处理方式。
参数传递
Rust 函数可以接受零个或多个参数。每个参数都必须显式声明其类型,这有助于编译器在编译时进行类型检查,从而保证类型安全。
fn greet(name: &str, age: u32) {
println!("你好,{}!你 {} 岁了。", name, age);
}
fn main() {
greet("Alice", 30);
}
在上面的例子中,greet 函数有两个参数:name 是一个字符串切片引用(&str),age 是一个无符号 32 位整数(u32)。
Rust 中的参数传递主要遵循所有权规则。根据参数的类型和函数签名,数据可以以以下三种方式传递:
传递所有权(Move):当参数类型是
T(非引用)时,函数将获得该值的所有权。调用者将无法再使用该值。fn take_ownership(s: String) { println!("我拥有了这个字符串: {}", s); } // 在这里,s 被释放 fn main() { let my_string = String::from("Hello"); take_ownership(my_string); // println!("{}", my_string); // 编译错误!my_string 的所有权已被转移 }不可变借用(
&T):函数可以借用值而不获取所有权。这允许函数读取数据,但不能修改它。调用者在函数调用后仍然可以使用该值。fn borrow_string(s: &String) { println!("我借用了这个字符串: {}", s); } // 借用结束,s 被归还 fn main() { let my_string = String::from("Hello"); borrow_string(&my_string); // 传递引用 println!("我仍然拥有它: {}", my_string); // 正常工作 }可变借用(
&mut T):函数可以借用并修改值。这要求调用者传递一个可变引用。fn modify_string(s: &mut String) { s.push_str(", world!"); } fn main() { let mut my_string = String::from("Hello"); modify_string(&mut my_string); // 传递可变引用 println!("修改后的字符串: {}", my_string); // 输出: "修改后的字符串: Hello, world!" }
选择哪种传递方式取决于函数的意图:是需要拥有数据、只读访问数据,还是需要修改数据。
返回值
函数可以返回一个值,也可以不返回任何值(隐式返回单元类型 ())。返回值的类型必须在函数签名中通过箭头 -> 指定。
返回所有权:最常见的返回值方式。函数将值的所有权返回给调用者。
fn create_string() -> String { let s = String::from("Created"); s // 返回 s 的所有权 } fn main() { let my_string = create_string(); println!("{}", my_string); // 输出: "Created" }返回引用:函数可以返回对函数内部数据的引用,但必须遵守生命周期规则。不能返回对函数内部局部变量的引用,因为局部变量在函数结束时会被销毁,导致悬垂引用。
fn return_ref(s: &String) -> &String { &s[..] // 返回对传入字符串切片的一部分的引用 } fn main() { let my_string = String::from("Hello, world!"); let part = return_ref(&my_string); println!("{}", part); // 输出: "Hello, world!" }返回多个值:Rust 不支持直接返回多个值,但可以通过元组(tuple)来返回一组值。
fn calculate_length(s: String) -> (String, usize) { let length = s.len(); (s, length) // 返回元组,包含原始字符串和其长度 } fn main() { let my_string = String::from("Hello"); let (new_string, len) = calculate_length(my_string); println!("字符串 '{}' 的长度是 {}。", new_string, len); }
隐式返回与表达式
Rust 是一种基于表达式的语言。函数体中的最后一个表达式(不带分号)会作为返回值隐式返回。
fn add(x: i32, y: i32) -> i32 {
x + y // 这是一个表达式,其值被隐式返回
}
fn main() {
let sum = add(5, 3);
println!("和是: {}", sum); // 输出: "和是: 8"
}
这比使用显式的 return 语句更简洁。return 关键字通常用于提前返回。
总结
- 函数参数必须声明类型,并通过所有权、不可变借用或可变借用来传递。
- 返回值通过
->指定类型,可以返回所有权或引用。 - 使用元组可以返回多个值。
- 利用表达式隐式返回值可以使代码更简洁。
掌握这些概念后,你将能更灵活、更安全地设计函数接口,为构建复杂的 Rust 程序打下坚实的基础。
