这是一个向量的示例,该向量传递给一个函数,该函数将值相加并将相同的向量传递给另一个对其进行排序的函数。
fn bubble_sort(mut arr: Vec<i32>) {
let mut swapped = true;
while swapped {
swapped = false;
for i in 0..arr.len()-1 {
if arr[i] > arr[i + 1] {
let tmp = arr[i];
let arr[i] = arr[i + 1];
let arr[i + 1] = tmp;
swapped = true;
}
}
}
}
fn populate(n: i32, mut &factors: Vec<i32>) {
factors.push(2);
factors.push(2);
factors.push(n);
factors.push(41);
bubble_sort(factors);
}
fn main() {
let mut factors: Vec<i32> = Vec::new();
populate(164, &factors);
println!("Factors {:?}", factors);
}
编译器已尽力帮助我,但无济于事。你能帮忙吗?我知道有库排序方法,对我来说关键问题是更改向量值。
让我们回顾一下错误。首先,我们有两个相同的。
error: expected a pattern, found an expression
--> src/main.rs:8:21
|
8 | let arr[i] = arr[i + 1];
| ^^^^^^ arbitrary expressions are not allowed in patterns
error: expected a pattern, found an expression
--> src/main.rs:9:21
|
9 | let arr[i + 1] = tmp;
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
let
仅在声明新变量时使用。如果您只想分配给现有变量,则不要使用 let
。
// let arr[i] = arr[i + 1];
// let arr[i + 1] = tmp;
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
我将跳过下一个错误并转到第四个错误。
error[E0308]: mismatched types
--> src/main.rs:16:21
|
16 | fn populate(n: i32, mut &factors: Vec<i32>) {
| ^^^^^^^^^^^^ -------- expected due to this
| |
| expected `Vec<i32>`, found `&_`
|
= note: expected struct `Vec<i32>`
found reference `&_`
help: to take parameter `factors` by reference, move `&` to the type
|
16 - fn populate(n: i32, mut &factors: Vec<i32>) {
16 + fn populate(n: i32, factors: &Vec<i32>) {
|
在 Rust 中,参数遵循
PATTERN: TYPE
语法。对于大多数参数,PATTERN
是单个名称。 TYPE
完全确定您传递给函数的内容。您正在寻找一个需要引用的函数,所以让我们应用编译器的建议,暂时忽略 mut
。
// fn populate(n: i32, mut &factors: Vec<i32>) {
fn populate(n: i32, factors: &Vec<i32>) {
尝试再次编译,我们收到另一个错误。
error[E0308]: mismatched types
--> src/main.rs:21:17
|
21 | bubble_sort(factors);
| ----------- ^^^^^^^- help: try using a conversion method: `.to_vec()`
| | |
| | expected `Vec<i32>`, found `&Vec<i32>`
| arguments to this function are incorrect
|
= note: expected struct `Vec<_>`
found reference `&Vec<_>`
note: function defined here
--> src/main.rs:1:4
|
1 | fn bubble_sort(mut arr: Vec<i32>) {
| ^^^^^^^^^^^ -----------------
Rust 的借用模型分为三个级别:拥有的 (
T
)、可变引用 (&mut T
) 和共享引用 (&T
)。您可以将列表中较早的值转换为列表中较晚的值,但反之则不行。
在这里,您的
populate
函数具有 &Vec<i32>
(共享引用),而 bubble_sort
需要 Vec<i32>
(拥有值)。编译器建议使用 .to_vec()
,它会复制 Vec
。这将使代码编译,但它不会执行您想要的操作,因为 bubble_sort
将在新的独立值上运行。
您可以升级
populate
以获取拥有的 Vec<i32>
,但让我们降级 bubble_sort
以获取 &Vec<i32>
。
// fn bubble_sort(mut arr: Vec<i32>) {
fn bubble_sort(arr: &Vec<i32>) {
现在,当我们编译时,我们收到六个相同的错误,其中有两个建议修复。
error[E0596]: cannot borrow `*arr` as mutable, as it is behind a `&` reference
--> src/main.rs:8:17
|
8 | arr[i] = arr[i + 1];
| ^^^ `arr` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
1 | fn bubble_sort(arr: &mut Vec<i32>) {
| +++
error[E0596]: cannot borrow `*factors` as mutable, as it is behind a `&` reference
--> src/main.rs:17:5
|
17 | factors.push(2);
| ^^^^^^^ `factors` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
16 | fn populate(n: i32, factors: &mut Vec<i32>) {
| +++
这些都很容易理解。我们想要改变
Vec
,所以我们必须可变地借用它。应用这两项修复后,我们就只剩下一个错误了。
// fn populate(n: i32, factors: &Vec<i32>) {
fn populate(n: i32, factors: &mut Vec<i32>) {
// fn bubble_sort(arr: &Vec<i32>) {
fn bubble_sort(arr: &mut Vec<i32>) {
最后一个错误:
error[E0308]: mismatched types
--> src/main.rs:26:19
|
26 | populate(164, &factors);
| -------- ^^^^^^^^ types differ in mutability
| |
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut Vec<_>`
found reference `&Vec<_>`
note: function defined here
--> src/main.rs:16:4
|
16 | fn populate(n: i32, factors: &mut Vec<i32>) {
| ^^^^^^^^ ----------------------
请记住,我们在函数签名中将此参数从共享引用升级为可变引用,因此我们需要对调用站点执行相同的操作。
// populate(164, &factors);
populate(164, &mut factors);
而且它有效!您可以在 Playground here 上尝试完整的代码。
经常让人困惑的一件事是何时将
mut
放在变量名称之前以及何时将其放在变量名称之后。这篇文章对此进行了解释:在变量名之前和“:”之后放置“mut”有什么区别?