参数与返回值 #
一、参数传递 #
1.1 值传递 #
rust
fn double(mut x: i32) -> i32 {
x *= 2;
x
}
fn main() {
let a = 5;
let b = double(a);
println!("a = {}, b = {}", a, b); // a = 5, b = 10
}
1.2 引用传递 #
rust
fn print_length(s: &String) {
println!("Length: {}", s.len());
}
fn main() {
let s = String::from("hello");
print_length(&s);
println!("s still valid: {}", s);
}
1.3 可变引用 #
rust
fn push_str(s: &mut String, suffix: &str) {
s.push_str(suffix);
}
fn main() {
let mut s = String::from("hello");
push_str(&mut s, ", world");
println!("{}", s);
}
二、多返回值 #
2.1 元组返回 #
rust
fn divide(dividend: i32, divisor: i32) -> (i32, i32) {
(dividend / divisor, dividend % divisor)
}
fn main() {
let (quotient, remainder) = divide(10, 3);
println!("商: {}, 余数: {}", quotient, remainder);
}
2.2 解构返回值 #
rust
fn min_max(numbers: &[i32]) -> (i32, i32) {
let mut min = numbers[0];
let mut max = numbers[0];
for &num in numbers {
if num < min { min = num; }
if num > max { max = num; }
}
(min, max)
}
fn main() {
let numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
let (min, max) = min_max(&numbers);
println!("最小: {}, 最大: {}", min, max);
}
三、Option 返回 #
3.1 返回 Option #
rust
fn find_first_even(numbers: &[i32]) -> Option<usize> {
for (i, &num) in numbers.iter().enumerate() {
if num % 2 == 0 {
return Some(i);
}
}
None
}
fn main() {
let numbers = vec![1, 3, 5, 4, 7];
match find_first_even(&numbers) {
Some(index) => println!("第一个偶数索引: {}", index),
None => println!("没有偶数"),
}
}
3.2 使用 ? 运算符 #
rust
fn get_last_char(s: &str) -> Option<char> {
s.chars().last()
}
fn process(s: &str) -> Option<String> {
let c = get_last_char(s)?;
Some(format!("最后一个字符: {}", c))
}
fn main() {
println!("{:?}", process("hello"));
println!("{:?}", process(""));
}
四、Result 返回 #
4.1 返回 Result #
rust
fn divide_checked(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err(String::from("除数不能为零"))
} else {
Ok(a / b)
}
}
fn main() {
match divide_checked(10, 2) {
Ok(result) => println!("结果: {}", result),
Err(e) => println!("错误: {}", e),
}
match divide_checked(10, 0) {
Ok(result) => println!("结果: {}", result),
Err(e) => println!("错误: {}", e),
}
}
4.2 错误传播 #
rust
use std::fs::File;
use std::io::{self, Read};
fn read_file_content(path: &str) -> io::Result<String> {
let mut file = File::open(path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
Ok(content)
}
fn main() {
match read_file_content("test.txt") {
Ok(content) => println!("内容: {}", content),
Err(e) => println!("错误: {}", e),
}
}
五、默认参数 #
Rust不支持默认参数,但可以使用其他方式:
5.1 使用 Option #
rust
fn greet(name: &str, greeting: Option<&str>) {
let greeting = greeting.unwrap_or("Hello");
println!("{}, {}!", greeting, name);
}
fn main() {
greet("Alice", None);
greet("Bob", Some("Hi"));
}
5.2 使用结构体 #
rust
struct GreetOptions {
name: String,
greeting: String,
punctuation: String,
}
impl GreetOptions {
fn new(name: &str) -> Self {
GreetOptions {
name: name.to_string(),
greeting: String::from("Hello"),
punctuation: String::from("!"),
}
}
fn greeting(mut self, greeting: &str) -> Self {
self.greeting = greeting.to_string();
self
}
fn punctuation(mut self, punctuation: &str) -> Self {
self.punctuation = punctuation.to_string();
self
}
fn build(self) -> String {
format!("{}, {}{}", self.greeting, self.name, self.punctuation)
}
}
fn main() {
let msg = GreetOptions::new("Alice")
.greeting("Hi")
.punctuation(".")
.build();
println!("{}", msg);
}
六、可变参数 #
6.1 使用宏 #
rust
fn main() {
println!("Sum: {}", sum!(1, 2, 3, 4, 5));
}
macro_rules! sum {
($($x:expr),*) => {
{
let mut total = 0;
$(
total += $x;
)*
total
}
};
}
6.2 使用切片 #
rust
fn sum(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
fn main() {
let result = sum(&[1, 2, 3, 4, 5]);
println!("Sum: {}", result);
}
七、函数指针 #
7.1 函数类型 #
rust
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn multiply(a: i32, b: i32) -> i32 {
a * b
}
fn calculate(op: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {
op(a, b)
}
fn main() {
let result1 = calculate(add, 5, 3);
let result2 = calculate(multiply, 5, 3);
println!("add: {}", result1);
println!("multiply: {}", result2);
}
7.2 函数作为返回值 #
rust
fn get_operator(op: &str) -> Option<fn(i32, i32) -> i32> {
match op {
"+" => Some(add),
"*" => Some(multiply),
_ => None,
}
}
fn add(a: i32, b: i32) -> i32 { a + b }
fn multiply(a: i32, b: i32) -> i32 { a * b }
fn main() {
if let Some(op) = get_operator("+") {
println!("Result: {}", op(5, 3));
}
}
八、实践示例 #
8.1 链式处理 #
rust
fn process(s: String) -> String {
s
}
fn add_prefix(mut s: String) -> String {
s.insert_str(0, "Prefix: ");
s
}
fn add_suffix(mut s: String) -> String {
s.push_str(" [Suffix]");
s
}
fn main() {
let result = process(String::from("hello"))
.pipe(add_prefix)
.pipe(add_suffix);
println!("{}", result);
}
trait Pipe<T> {
fn pipe<F>(self, f: F) -> T where F: FnOnce(Self) -> T;
}
impl<T> Pipe<T> for T {
fn pipe<F>(self, f: F) -> T where F: FnOnce(Self) -> T {
f(self)
}
}
8.2 回调函数 #
rust
fn process_with_callback(data: &[i32], callback: fn(i32) -> i32) -> Vec<i32> {
data.iter().map(|&x| callback(x)).collect()
}
fn double(x: i32) -> i32 { x * 2 }
fn square(x: i32) -> i32 { x * x }
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled = process_with_callback(&numbers, double);
println!("Doubled: {:?}", doubled);
let squared = process_with_callback(&numbers, square);
println!("Squared: {:?}", squared);
}
九、总结 #
本章学习了:
- 参数传递方式
- 多返回值处理
- Option 和 Result 返回
- 默认参数替代方案
- 可变参数处理
- 函数指针
下一章,我们将学习闭包与迭代器。
最后更新:2026-03-27