我写了一个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
}
如果我在调用my_array
时输入相同的min
参数,Rust会报错:
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
如何编写有效的代码?
答案 0 :(得分:10)
这是Rust的初学者将遇到的问题。作为初学者,您应该阅读The Rust Programming Language。本书付出了很多努力,尤其是Rust的新手。这将涵盖您将遇到的许多事情。
相关部分:
潜在的问题是,当您致电max
时,您已转移了向量的所有权。然后价值消失了; main
不再拥有它。
最简单的方法是在传递给max
之前克隆向量。这样,main
可以保留my_array
的所有权,然后在后续行中将所有权转移到min
:
let max = max(my_array.clone());
let min = min(my_array);
这是低效的,因为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
}
在切片上进行迭代时,您将获得对切片中项目的引用。对于整数,我们可以取消引用它们(这里使用&
中的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
和Iterator::max
,
每个返回Option
,作为空切片没有最小值或最大值。
从技术上讲,它与原始解决方案略有不同,因为min
和max
是Option<&i32>
;对原始切片的引用。您可以使用Option::cloned
:
Option<i32>
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);
}
奖励信息:切片,Vec
和数组都是不同的类型。将my_array
称为数组是不正确的。