Rust 中的返回类型

一、基础返回类型

1. 显式指定类型

rust 复制代码
fn add(a: i32, b: i32) -> i32 {
    a + b  // 隐式返回(无分号)
}

2. 单元类型 () (类似 void)

rust 复制代码
fn print_hello() -> () {
    println!("Hello");
    // 等价于不写返回类型
}

二、高级返回类型

1. 返回复合类型
rust 复制代码
// 返回元组
fn get_coords() -> (f64, f64) {
    (3.14, -1.23)
}

// 返回结构体
struct Point { x: i32, y: i32 }
fn new_point(x: i32, y: i32) -> Point {
    Point { x, y }
}
2. 返回引用(需生命周期注解)
rust 复制代码
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() { s1 } else { s2 }
}
3. 返回智能指针
rust 复制代码
// 返回 Box(堆分配)
fn create_box() -> Box<i32> {
    Box::new(42)
}

// 返回 Rc(引用计数)
use std::rc::Rc;
fn shared_data() -> Rc<String> {
    Rc::new("Shared".to_string())
}

三、错误处理返回类型

1. Option<T> (可能缺失值)
rust 复制代码
fn find_item(list: &[i32], target: i32) -> Option<usize> {
    list.iter().position(|&x| x == target)
}
2. Result<T, E> (可能失败操作)
rust 复制代码
use std::fs::File;

fn open_file(path: &str) -> Result<File, std::io::Error> {
    File::open(path)
}

四、特殊返回模式

1. 返回闭包
rust 复制代码
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
    move |y| x + y  // 使用 impl Trait 隐藏具体类型
}
2. 返回迭代器
rust 复制代码
fn even_numbers(nums: &[i32]) -> impl Iterator<Item = &i32> {
    nums.iter().filter(|&&n| n % 2 == 0)
}
3. Never 类型 ! (永不返回)
rust 复制代码
fn panic_forever() -> ! {
    loop {
        panic!("This function never returns");
    }
}

五、动态返回类型

1. Trait 对象(动态分发)
rust 复制代码
trait Draw { fn draw(&self); }

fn render_object() -> Box<dyn Draw> {
    // 返回实现 Draw 的不同类型
    if condition { Box::new(Circle) } 
    else { Box::new(Square) }
}
2. 使用 impl Trait (静态分发)
rust 复制代码
fn parse_input(input: &str) -> impl Iterator<Item = i32> + '_ {
    input.split(',').filter_map(|s| s.parse().ok())
}

六、实用技巧与陷阱

  1. 最后一行的表达式隐式返回

    删除末尾分号使其成为表达式:

rust 复制代码
fn answer() -> i32 {
    let x = 40;
    x + 2  // 无分号,返回 42
}

2. 提前返回用 return

rust 复制代码
fn safe_div(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 {
        return None; // 提前退出
    }
    Some(a / b)
}

3. 避免返回临时值的引用

rust 复制代码
// 错误示例:返回局部变量引用
fn invalid_ref() -> &str {
    let s = String::from("hello");
    &s  // 编译错误:s 的生命周期不足
}

// 正确做法:返回所有权
fn valid_owner() -> String {
    String::from("hello")
}

七、类型推导简化

Rust 支持局部类型推导,但函数签名必须显式声明返回类型

rust 复制代码
fn main() {
    let x = 42;        // 编译器推导为 i32
}

// 但函数必须声明返回类型
fn get_value() -> i32 { // 必须显式指定
    42
}

总结表格

返回类型 适用场景 关键特点
基础类型 (i32等) 简单计算 栈分配,高效
Option<T> 可能缺失值的操作 强制错误处理
Result<T,E> 可能失败的操作 显式错误传播
impl Trait 返回复杂但类型单一的实现 简化签名,静态分发
Box<dyn Trait> 返回不同类型但同一 Trait 的对象 动态分发,运行时开销
智能指针 (Rc, Arc) 共享所有权场景 避免拷贝,管理生命周期
相关推荐
码事漫谈12 分钟前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
hoiii18729 分钟前
CSTR反应器模型的Simulink-PID仿真(MATLAB实现)
开发语言·matlab
炘爚1 小时前
C++ 右值引用与程序优化
开发语言·c++
码农BookSea1 小时前
ReAct:让大模型学会边想边做
后端·ai编程
si莉亚1 小时前
ROS2安装EVO工具包
linux·开发语言·c++·开源
清心歌1 小时前
CopyOnWriteArrayList 实现原理
java·开发语言
码农BookSea1 小时前
10分钟掌握 JSON-RPC 协议,面试加分、设计不踩坑
后端
数据知道2 小时前
claw-code 源码分析:从 TypeScript 心智到 Python/Rust——跨栈移植时类型、边界与错误模型怎么对齐?
python·ai·rust·typescript·claude code·claw code
良木生香2 小时前
【C++初阶】C++入门相关知识(2):输入输出 & 缺省参数 & 函数重载
开发语言·c++
忘梓.2 小时前
墨色规则与血色节点:C++红黑树设计与实现探秘
java·开发语言·c++