Rust 函数如何返回值

· 1109 words · 6 min

在 Rust 中,函数通过返回值来输出计算结果。Rust 函数的返回值是函数体最后一个表达式的值,或者显式使用 return 关键字。与许多其他语言不同,Rust 函数没有 return 关键字时,返回的是最后一个表达式的值,且该表达式不能有分号

函数返回值的基本语法

隐式返回(无 return 关键字)

Rust 的惯用方式是使用函数体最后一个表达式的值作为返回值。这种情况下,返回值不需要 return 关键字,而且最后的表达式不能加分号,否则它会被视为语句,而不是表达式。

fn add(x: i32, y: i32) -> i32 {
    x + y  // 最后一个表达式,没有分号,作为返回值
}

fn main() {
    let result = add(2, 3);
    println!("Result: {}", result); // 输出: Result: 5
}

这里 x + y 是最后一个表达式,它的值(即 x + y 的计算结果)将作为函数的返回值。

显式返回(使用 return 关键字)

你也可以显式地使用 return 关键字在函数中返回一个值。这样做会立即结束函数并返回指定的值。

fn add(x: i32, y: i32) -> i32 {
    return x + y;  // 使用 return 关键字,提前返回
}

fn main() {
    let result = add(2, 3);
    println!("Result: {}", result); // 输出: Result: 5
}

使用 return 时,即使加上分号,return 也会立即返回值,不会影响函数行为。

返回 () 单元类型

如果函数不需要显式返回值,默认返回 () 类型,称为单元类型。这种函数类似于其他语言中的 void 类型函数。

fn print_message() {
    println!("This is a message.");
    // 没有返回值,实际上返回的是 `()`
}

fn main() {
    print_message(); // 输出: This is a message.
}

print_message 函数没有显式的返回值,因此它返回 (),即单元类型。

返回多个值

Rust 没有直接支持多返回值,但你可以通过使用元组来返回多个值。

fn swap(x: i32, y: i32) -> (i32, i32) {
    (y, x)  // 返回一个元组
}

fn main() {
    let (a, b) = swap(1, 2);
    println!("Swapped: a = {}, b = {}", a, b); // 输出: Swapped: a = 2, b = 1
}

函数 swap 返回一个 (i32, i32) 元组,调用时可以通过元组解构来获取各个返回值。

返回引用或指针

Rust 允许函数返回引用或者智能指针类型(如 Box<T>)。当返回引用时,需要确保引用的生命周期符合 Rust 的借用检查规则。

fn largest<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
    if x > y {
        x
    } else {
        y
    }
}

fn main() {
    let a = 5;
    let b = 10;
    let result = largest(&a, &b);
    println!("The largest number is {}", result); // 输出: The largest number is 10
}

这里的 largest 函数返回两个引用中较大的一个。为了满足 Rust 的借用检查器,返回的引用必须带有生命周期标注。

返回 ResultOption 类型

Rust 以安全著称,通常使用 ResultOption 来处理可能失败的操作或可能没有值的情况。这样的返回值为函数调用者提供了错误处理的机制。

Result 示例:

fn divide(x: i32, y: i32) -> Result<i32, String> {
    if y == 0 {
        Err("Cannot divide by zero".to_string())
    } else {
        Ok(x / y)
    }
}

fn main() {
    match divide(10, 2) {
        Ok(result) => println!("Result: {}", result), // 输出: Result: 5
        Err(e) => println!("Error: {}", e),
    }
}

Option 示例:

fn find_item(items: &[i32], target: i32) -> Option<usize> {
    for (index, &item) in items.iter().enumerate() {
        if item == target {
            return Some(index);
        }
    }
    None
}

fn main() {
    let items = [1, 2, 3, 4, 5];
    match find_item(&items, 3) {
        Some(index) => println!("Found at index {}", index), // 输出: Found at index 2
        None => println!("Item not found"),
    }
}

Result<T, E> 用于可能失败的操作,返回 Ok(T) 表示成功,Err(E) 表示错误。

Option<T> 用于可能没有值的情况,Some(T) 表示有值,None 表示无值。

总结

Rust