【问题标题】:How to pass one Vec to multiple functions in Rust?如何将一个 Vec 传递给 Rust 中的多个函数?
【发布时间】:2017-08-14 16:57:29
【问题描述】:

我写了一个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
}

如果我将相同的my_array 参数放在对min 的调用中,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

如何编写有效的代码?

【问题讨论】:

标签: vector rust ownership


【解决方案1】:

这是 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 &amp;val in array 中的 &amp;)并复制值。

另见:


更好的是,不需要像这样重写基本函数。您还假设始终至少有一个值,但对于空向量而言并非如此。惯用的解决方案是使用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::minIterator::max, 每个都返回一个Option,因为一个空切片没有最小值或最大值。

从技术上讲,它与您的原始解决方案略有不同,因为 minmaxOption&lt;&amp;i32&gt;;对原始切片的引用。你可以使用Option::copied返回Option&lt;i32&gt;

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 称为数组是不正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 2021-10-05
    • 2023-01-11
    • 2017-01-14
    相关资源
    最近更新 更多