如何将一个 Vec 传递给 Rust 中的多个函数?

How to pass one Vec to multiple functions in Rust?

我写了一个 max 函数,它接受一个 Vec 作为参数。它按我的预期工作。然后我添加了一个与max函数相同的min函数:

fn main() {
    let my_array = vec![61, 14, 71, 23, 42, 8, 13, 66];
    let max = max(my_array);
    let min = min(my_array);
    println!("Max value is {}.", max);
}

fn max(array: Vec<i32>) -> i32 {
    let mut max = array[0];
    for val in array {
        if max < val {
            max = val;
        }
    }
    max
}

fn min(array: Vec<i32>) -> i32 {
    let mut min = array[0];
    for val in array {
        if min > val {
            min = val;
        }
    }
    min
}

如果我在对 min 的调用中放置相同的 my_array 参数,Rust 会报告错误:

error[E0382]: use of moved value: `my_array`
 --> src/main.rs:4:19
  |
2 |     let my_array = vec![61, 14, 71, 23, 42, 8, 13, 66];
  |         -------- move occurs because `my_array` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 |     let max = max(my_array);
  |                   -------- value moved here
4 |     let min = min(my_array);
  |                   ^^^^^^^^ value used here after move

我怎样才能编写有效的代码?

这是 Rust 初学者都会遇到的问题。作为初学者,你应该阅读The Rust Programming Language。本书倾注了大量心血,尤其是对于 Rust 新手而言。这将涵盖您将 运行 了解的许多内容。

相关章节:


潜在的问题是当您调用 max 时,您已经 转移了向量的所有权 。然后价值就消失了; main 没有了。

最简单的方法是在传递给 max 之前克隆向量。这允许 main 保留 my_array 的所有权,然后在后续行中将所有权转让给 min

let max = max(my_array.clone());
let min = min(my_array);

这是低效的,因为 maxmin 都不需要取得矢量的所有权来完成它们的工作。克隆 Vec 还需要分配额外的内存。传递 slice 更为惯用,这是对 Vec:

中数据的一种引用类型
let max = max(&my_array);
let min = min(&my_array);
fn max(array: &[i32]) -> i32 {
    let mut max = array[0];
    for &val in array {
        if max < val {
            max = val;
        }
    }
    max
}

迭代切片时,您会返回对切片中项目的引用。对于整数,我们可以取消引用它们(这里使用 for &val in array 中的 &)并复制该值。

另请参阅:


更好的是,无需像这样重写基本功能。您还假设总是至少有一个值,但对于空向量而言则不成立。惯用的解决方案是使用 iterators:

fn main() {
    let my_array = vec![61, 14, 71, 23, 42, 8, 13, 66];
    let max = my_array.iter().max();
    let min = my_array.iter().min();
    println!("Max value is {:?}.", max);
    println!("Min value is {:?}.", min);
}

这使用了Iterator::min and Iterator::max, 其中每个 return 一个 Option,因为一个空切片没有最小值或最大值。

从技术上讲,它与您最初的解决方案略有不同,因为 minmaxOption<&i32>;对原始切片的引用。您可以使用 Option::copied:

回到 Option<i32>
fn main() {
    let my_array = vec![61, 14, 71, 23, 42, 8, 13, 66];
    let max = my_array.iter().max().copied();
    let min = my_array.iter().min().copied();
    println!("Max value is {:?}.", max);
    println!("Min value is {:?}.", min);
}

额外信息:切片、Vecs 和数组都是不同的类型。将 my_array 称为数组是不正确的。