一、基础返回类型
1. 显式指定类型
fn add(a: i32, b: i32) -> i32 {
a + b // 隐式返回(无分号)
}
2. 单元类型 ()
(类似 void)
fn print_hello() -> () {
println!("Hello");
// 等价于不写返回类型
}
二、高级返回类型
1. 返回复合类型
// 返回元组
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. 返回引用(需生命周期注解)
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s1.len() > s2.len() { s1 } else { s2 }
}
3. 返回智能指针
// 返回 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>
(可能缺失值)
fn find_item(list: &[i32], target: i32) -> Option<usize> {
list.iter().position(|&x| x == target)
}
2. Result<T, E>
(可能失败操作)
use std::fs::File;
fn open_file(path: &str) -> Result<File, std::io::Error> {
File::open(path)
}
四、特殊返回模式
1. 返回闭包
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
move |y| x + y // 使用 impl Trait 隐藏具体类型
}
2. 返回迭代器
fn even_numbers(nums: &[i32]) -> impl Iterator<Item = &i32> {
nums.iter().filter(|&&n| n % 2 == 0)
}
3. Never 类型 !
(永不返回)
fn panic_forever() -> ! {
loop {
panic!("This function never returns");
}
}
五、动态返回类型
1. Trait 对象(动态分发)
trait Draw { fn draw(&self); }
fn render_object() -> Box<dyn Draw> {
// 返回实现 Draw 的不同类型
if condition { Box::new(Circle) }
else { Box::new(Square) }
}
2. 使用 impl Trait
(静态分发)
fn parse_input(input: &str) -> impl Iterator<Item = i32> + '_ {
input.split(',').filter_map(|s| s.parse().ok())
}
六、实用技巧与陷阱
最后一行的表达式隐式返回
删除末尾分号使其成为表达式:
fn answer() -> i32 {
let x = 40;
x + 2 // 无分号,返回 42
}
2. 提前返回用 return
fn safe_div(a: f64, b: f64) -> Option<f64> {
if b == 0.0 {
return None; // 提前退出
}
Some(a / b)
}
3. 避免返回临时值的引用
// 错误示例:返回局部变量引用
fn invalid_ref() -> &str {
let s = String::from("hello");
&s // 编译错误:s 的生命周期不足
}
// 正确做法:返回所有权
fn valid_owner() -> String {
String::from("hello")
}
七、类型推导简化
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 ) |
共享所有权场景 | 避免拷贝,管理生命周期 |