009 Rust函数
Rust函数定义形式
fn <函数名>([参数])[->返回值类型]{<函数体>
}
如下:
fn add(a:i32, b:i32)->i32{return a + b;
}
Rust 函数名称的命名风格小写字母以下划线分割
,如get_soft_version()
。
函数参数和函数返回值可以没有,如下:
fn hello() {println!("{}", add(1,2));
}
与 C/C++ 不同,Rust 中函数定义的顺序没有限制,可以函数调用在函数定义之前, Rust不在乎您在何处定义函数,只需在某个地方定义它们即可。如下:
fn main() {println!("Hello, world!");say_hello(); // 函数调用在定义之前
}// 函数定义
fn say_hello() {println!("Hello, CSDN!");
}
函数参数
Rust 中定义函数如果需要具备参数必须声明参数名称和类型:
fn add(a:i32, b:i32)->i32{return a + b;
}
函数体
Rust 函数体由一系列由表达式(Expression)结尾的语句(Statement)组成。
语句是执行某些操作且没有返回值的步骤。例如:
let a = 6;
这个步骤没有返回值,所以下面语句不正确:
let a = (let b = 2);
表达式有计算步骤且有返回值。如下:
// 这里假设已声明a、b、c变量
a = 7
b + 2
c * (a + b)
在 Rust 中,函数定义可以嵌套:
fn main() {fn one_two() -> i32 {12}println!("one_two() 的值为: {}", one_two());
}
函数返回值
上一个嵌套的例子中已使用 Rust 函数声明返回值类型的方式:在参数声明之后用 ->
来声明函数返回值的类型。
在函数体中,随时都可以用 return 关键字结束函数并返回一个类型合适的值。
fn add(a: i32, b: i32) -> i32 {return a + b;
}
Rust 不支持自动返回值类型推断,如果有返回值必须声明返回值类型。
Rust 函数的最后一个表达式将作为返回值,无return关键字、结尾没有分号,如下:
fn add(a: i32, b: i32) -> i32 {a + b
}
注意:一定要是最后一个表达式的值,才能作为默认返回值。
函数返回多个值
在 Rust 中,函数可以返回多个值,主要通过以下几种方式实现:
- 返回元组:
fn calculate_stats(numbers: &[i32]) -> (i32, i32, f64) {let min = *numbers.iter().min().unwrap_or(&0);let max = *numbers.iter().max().unwrap_or(&0);let sum: i32 = numbers.iter().sum();let avg = sum as f64 / numbers.len() as f64;(min, max, avg)
}fn main() {let numbers = [1, 2, 3, 4, 5];let (min, max, avg) = calculate_stats(&numbers);println!("最小值: {}, 最大值: {}, 平均值: {:.2}", min, max, avg);
}
- 返回结构体(Struct)
当返回的数据有明确含义时,使用结构体更清晰:
struct Stats {min: i32,max: i32,avg: f64,
}fn calculate_stats(numbers: &[i32]) -> Stats {let min = *numbers.iter().min().unwrap_or(&0);let max = *numbers.iter().max().unwrap_or(&0);let sum: i32 = numbers.iter().sum();let avg = sum as f64 / numbers.len() as f64;Stats { min, max, avg }
}fn main() {let numbers = [1, 2, 3, 4, 5];let stats = calculate_stats(&numbers);println!("最小值: {}, 最大值: {}, 平均值: {:.2}", stats.min, stats.max, stats.avg);
}
3. 返回数组或向量
当所有返回值类型相同时,可以使用数组或向量:
fn get_coordinates() -> [f64; 3] {[10.5, 20.3, 5.7]
}fn main() {let [x, y, z] = get_coordinates();println!("坐标: x={}, y={}, z={}", x, y, z);
}
4. 返回元组结构体
struct Point(f64, f64, f64);fn get_point() -> Point {Point(10.5, 20.3, 5.7)
}fn main() {let Point(x, y, z) = get_point();println!("点坐标: x={}, y={}, z={}", x, y, z);
}
5. 返回 Result或 Option
处理可能失败的操作时,可以返回多个结果:
fn divide(a: f64, b: f64) -> Result<f64, String> {if b == 0.0 {Err("除数不能为零".to_string())} else {Ok(a / b)}
}fn calculate(a: f64, b: f64) -> (Option<f64>, Option<f64>) {let sum = a + b;let product = a * b;(Some(sum), Some(product))
}fn main() {match divide(10.0, 2.0) {Ok(result) => println!("除法结果: {}", result),Err(e) => println!("错误: {}", e),}let (sum, product) = calculate(3.0, 4.0);println!("和: {:?}, 积: {:?}", sum, product);
}
6. 返回自定义枚举
enum OperationResult {Success(i32, i32),Failure(String),
}fn perform_operation(a: i32, b: i32) -> OperationResult {if b == 0 {OperationResult::Failure("除数不能为零".to_string())} else {let sum = a + b;let product = a * b;OperationResult::Success(sum, product)}
}fn main() {match perform_operation(10, 5) {OperationResult::Success(sum, product) => {println!("和: {}, 积: {}", sum, product)}OperationResult::Failure(msg) => {println!("操作失败: {}", msg)}}
}
7. 返回引用或可变引用- 避免复制大对象
fn get_min_max(numbers: &[i32]) -> (Option<&i32>, Option<&i32>) {let min = numbers.iter().min();let max = numbers.iter().max();(min, max)
}fn main() {let numbers = [5, 2, 8, 1, 9];let (min, max) = get_min_max(&numbers);println!("最小值: {:?}, 最大值: {:?}", min, max);
}