009 Rust函数

Rust函数定义形式

rust 复制代码
fn <函数名>([参数])[->返回值类型]{
	<函数体>
}

如下:

rust 复制代码
fn add(a:i32, b:i32)->i32{
    return a + b;
}

Rust 函数名称的命名风格小写字母以下划线分割,如get_soft_version()
函数参数函数返回值可以没有,如下:

rust 复制代码
fn hello() {
    println!("{}", add(1,2));
}

与 C/C++ 不同,Rust 中函数定义的顺序没有限制,可以函数调用在函数定义之前, Rust不在乎您在何处定义函数,只需在某个地方定义它们即可。如下:

rust 复制代码
fn main() {
    println!("Hello, world!");
    say_hello(); // 函数调用在定义之前
}

// 函数定义
fn say_hello() {
    println!("Hello, CSDN!");
}

函数参数

Rust 中定义函数如果需要具备参数必须声明参数名称类型

rust 复制代码
fn add(a:i32, b:i32)->i32{
    return a + b;
}

函数体

Rust 函数体 由一系列由表达式(Expression)结尾的语句(Statement)组成。
语句是执行某些操作且没有返回值的步骤。例如:

rust 复制代码
let a = 6;

这个步骤没有返回值,所以下面语句不正确:

rust 复制代码
let a = (let b = 2);

表达式有计算步骤且有返回值。如下:

rust 复制代码
// 这里假设已声明a、b、c变量
a = 7
b + 2
c * (a + b)

在 Rust 中,函数定义可以嵌套:

rust 复制代码
fn main() {
    fn one_two() -> i32 {
        12
    }
    println!("one_two() 的值为: {}", one_two());
}

函数返回值

上一个嵌套的例子中已使用 Rust 函数声明返回值类型的方式:在参数声明之后用 -> 来声明函数返回值的类型。

在函数体中,随时都可以用 return 关键字结束函数并返回一个类型合适的值。

rust 复制代码
fn add(a: i32, b: i32) -> i32 {
    return a + b;
}

Rust 不支持自动返回值类型推断,如果有返回值必须声明返回值类型。
Rust 函数的最后一个表达式将作为返回值 ,无return关键字、结尾没有分号,如下:

rust 复制代码
 fn add(a: i32, b: i32) -> i32 {
    a + b
}

注意:一定要是最后一个表达式的值,才能作为默认返回值。

函数返回多个值

在 Rust 中,函数可以返回多个值,主要通过以下几种方式实现:

  1. 返回元组:
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);
}
  1. 返回结构体(Struct)
    当返回的数据有明确含义时,使用结构体更清晰:
rust 复制代码
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. 返回数组或向量

当所有返回值类型相同时,可以使用数组或向量:

rust 复制代码
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. 返回元组结构体

rust 复制代码
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

处理可能失败的操作时,可以返回多个结果:

rust 复制代码
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. 返回自定义枚举

rust 复制代码
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. 返回引用或可变引用- 避免复制大对象

rust 复制代码
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);
}
相关推荐
咩咩啃树皮1 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
灯澜忆梦2 小时前
GO_并发编程---定时器
开发语言·后端·golang
鱟鲥鳚2 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
-银雾鸢尾-2 小时前
C#中的StringBuilder相关方法
开发语言·c#
-银雾鸢尾-2 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白3 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司4 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地5 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun3141595 小时前
TCP超时重传机制是为了解决什么问题?
java
段一凡-华北理工大学5 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化