🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

📌 函数的基本定义

⚙️ 参数传递

🔄 返回值处理

🔗 函数与闭包

🧰 其他实用特性

💡 注意事项

📊 对比:函数与闭包


img

Rust 中的函数是其核心特性之一,用于封装可重用的代码块。下面我将为你梳理 Rust 函数的主要特点和使用方式。

📌 函数的基本定义

在 Rust 中,使用 fn 关键字定义函数。函数名应采用 ​​蛇形命名法​​(snake_case),即所有字母小写并用下划线分隔。

fn say_hello() {         // 定义一个无参数无返回值的函数
    println!("Hello, Rust!");
}

fn add(x: i32, y: i32) -> i32 {  // 定义带参数和返回值的函数
    x + y                        // 这是一个表达式,没有分号,因此作为返回值
}

fn main() {              // 主函数是程序的入口点
    say_hello();         // 调用函数
    let sum = add(5, 3); // 调用函数并将返回值绑定到变量 sum
    println!("5 + 3 = {}", sum);
}

⚙️ 参数传递

Rust 支持多种参数传递方式,具体取决于参数的类型和需求:

  1. ​值传递 (Pass by value)​​:默认用于基本类型(如 i32, f64)或结构体。函数内部对参数的修改不会影响原始变量。

    fn increment_by_value(mut num: i32) {
        num += 1; // 修改的是副本
        println!("Inside function: {}", num);
    }
  2. ​引用传递 (Pass by reference)​​:通过引用 (&),函数可以访问但不能修改原始数据,避免了数据拷贝。

    fn calculate_length(s: &String) -> usize {
        s.len() // 可以读取原始数据,但不能修改
    }
  3. ​可变引用传递 (Pass by mutable reference)​​:通过可变引用 (&mut),函数可以修改原始数据。

    fn add_mut(a: &mut i32, b: i32) {
        *a += b; // 解引用并修改原始值
    }

🔄 返回值处理

Rust 函数的返回值是通过 -> 在函数签名后声明的。

  • ​隐式返回​​:函数体中​​最后一个表达式​​的值会自动作为返回值(注意不能有分号)。
    fn multiply(a: f64, b: f64) -> f64 {
        a * b // 没有分号,这是一个表达式,其值作为返回值
    }
  • ​显式返回​​:使用 return 关键字可以提前返回。
    fn safe_divide(a: f64, b: f64) -> Option<f64> {
        if b == 0.0 {
            return None; // 提前返回 None
        }
        Some(a / b) // 正常返回
    }
  • ​多返回值​​:可以通过返回​​元组(tuple)​​ 来实现多个返回值。
    fn calculate(a: i32, b: i32) -> (i32, i32) {
        (a + b, a - b) // 返回一个包含和与差的元组
    }
  • ​特殊返回类型​​:
    • ​单元类型 ()​:类似于其他语言中的 void,表示没有返回值。函数如果没有显式指定返回类型,默认返回 ()
    fn no_return() -> () {
        println!("This function returns nothing.");
    }
    • ​发散函数 !​:用 -> ! 标记,表示函数永远不会返回(例如,无限循环或总是 panic)。
    fn forever() -> ! {
        loop {
            // 无限循环,永不返回
        }
    }

🔗 函数与闭包

Rust 支持​​高阶函数​​,即函数可以作为参数传递,也可以作为返回值。

  • ​函数作为参数​​:

    fn apply_operation(x: i32, y: i32, op: fn(i32, i32) -> i32) -> i32 {
        op(x, y)
    }
    
    fn add(a: i32, b: i32) -> i32 { a + b }
    
    let result = apply_operation(5, 3, add); // 传递函数 add 作为参数
  • ​闭包(匿名函数)​​:闭包是可以捕获其所在环境变量的匿名函数。它们使用 |参数| {函数体} 的语法定义。

    let factor = 2;
    let multiply = |x| x * factor; // 闭包捕获了外部变量 factor
    println!("{}", multiply(5)); // 输出 10

    闭包捕获环境变量的方式有三种,对应三个 Trait:

    • Fn:不可变借用环境中的变量。
    • FnMut:可变借用环境中的变量。
    • FnOnce:获取环境变量的所有权(通常因为闭包会将捕获的变量移出闭包体,如消耗掉)。

🧰 其他实用特性

  • ​泛型函数​​:可以编写适用于多种类型的函数,提高代码复用性。
    fn find_max<T: PartialOrd>(a: T, b: T) -> T {
        if a > b { a } else { b }
    }
  • ​方法​​:方法与函数类似,但方法是定义在结构体(或枚举、trait 对象)的上下文中,并且第一个参数通常是 self(表示调用该方法的结构体实例)。
    struct Rectangle { width: u32, height: u32 }
    impl Rectangle {
        fn area(&self) -> u32 { // 这是一个方法
            self.width * self.height
        }
    }

💡 注意事项

  • ​语句与表达式​​:Rust 中,表达式会返回值,而语句不会。函数体中最后一行如果是表达式,其值将作为返回值,​​切记不能加分号​​。如果加了分号,就变成了语句,不会返回任何值(即返回 ()),这常常会导致类型不匹配的错误。
  • ​生命周期​​:当函数参数和返回值包含引用时,通常需要​​生命周期注解​​来明确引用的有效范围,确保内存安全。这是一个进阶但重要的主题。
    fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
        if s1.len() > s2.len() { s1 } else { s2 }
    }

📊 对比:函数与闭包

特性 函数 (fn) 闭包
​命名​ 有名字 匿名
​捕获环境变量​ 不能
​类型​ 函数指针 fn() 实现 FnFnMutFnOnce trait 的匿名类型
​类型标注​ 必须显式标注参数和返回类型 通常可省略,编译器能推断

掌握 Rust 函数是编写安全高效程序的基础。希望这些信息能帮助你更好地理解和使用 Rust 函数。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐