Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • 搜索未来:SEO与GEO双引擎实战手册
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • Rust 开发入门
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • 搜索未来:SEO与GEO双引擎实战手册
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • Rust 开发入门
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain

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 中的参数传递主要遵循所有权规则。根据参数的类型和函数签名,数据可以以以下三种方式传递:

  1. 传递所有权(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 的所有权已被转移
    }
    
  2. 不可变借用(&T):函数可以借用值而不获取所有权。这允许函数读取数据,但不能修改它。调用者在函数调用后仍然可以使用该值。

    fn borrow_string(s: &String) {
        println!("我借用了这个字符串: {}", s);
    } // 借用结束,s 被归还
    
    fn main() {
        let my_string = String::from("Hello");
        borrow_string(&my_string); // 传递引用
        println!("我仍然拥有它: {}", my_string); // 正常工作
    }
    
  3. 可变借用(&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!"
    }
    

选择哪种传递方式取决于函数的意图:是需要拥有数据、只读访问数据,还是需要修改数据。

返回值

函数可以返回一个值,也可以不返回任何值(隐式返回单元类型 ())。返回值的类型必须在函数签名中通过箭头 -> 指定。

  1. 返回所有权:最常见的返回值方式。函数将值的所有权返回给调用者。

    fn create_string() -> String {
        let s = String::from("Created");
        s // 返回 s 的所有权
    }
    
    fn main() {
        let my_string = create_string();
        println!("{}", my_string); // 输出: "Created"
    }
    
  2. 返回引用:函数可以返回对函数内部数据的引用,但必须遵守生命周期规则。不能返回对函数内部局部变量的引用,因为局部变量在函数结束时会被销毁,导致悬垂引用。

    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!"
    }
    
  3. 返回多个值: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 程序打下坚实的基础。

Last Updated:: 5/9/26, 3:13 PM