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

taj*_*iro 2 rust

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

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
}
Run Code Online (Sandbox Code Playgroud)

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

error[E0382]: use of moved value: `my_array`
 --> src/main.rs:4:19
  |
3 |     let max = max(my_array);
  |                   -------- value moved here
4 |     let min = min(my_array);
  |                   ^^^^^^^^ value used here after move
  |
  = note: move occurs because `my_array` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)

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

She*_*ter 12

这是Rust的初学者将遇到的问题.作为初学者,您应该阅读The Rust Programming Language.本书付出了很多努力,尤其是Rust的新手.这将涵盖您将遇到的许多事情.

相关部分:


根本问题是你在调用时转移了向量的所有权max.然后价值消失了; main不再拥有它.

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

let max = max(my_array.clone());
let min = min(my_array);
Run Code Online (Sandbox Code Playgroud)

这是低效的,因为既不需要max也不min需要对矢量的所有权来完成他们的工作.克隆Vec还需要额外的内存分配.传递切片更加惯用,切片是对以下数据的一种引用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
}
Run Code Online (Sandbox Code Playgroud)

迭代切片时,您将获得对切片中项目的引用.使用整数,我们可以取消引用它们(这里使用&in for &val in array)并复制值.


更好的是,没有必要重写这样的基本功能.您还假设始终至少有一个值,对于空向量,这不是真的.惯用的解决方案是使用迭代器:

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);
}
Run Code Online (Sandbox Code Playgroud)

这使用Iterator::minIterator::max,每个返回一个Option,作为空切片没有最小值或最大值.

从技术上讲,它是从原始的解决方案略有不同,因为minmaxOption<&i32>; 对原始切片的引用.您可以Option<i32>使用Option::cloned以下命令返回:

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

奖励信息:切片,Vecs和数组都是不同的类型.根本不能将它my_array称为数组.