[英]Cannot move out of here move occurs because `slice[_]` has type `T`, which does not implement the `Copy` trait
I am trying to write quick sort in Rust, I got it working when I used the specific type [i32] but I get an error when I try to use [T].我正在尝试在 Rust 中编写快速排序,当我使用特定类型 [i32] 时它可以工作,但是当我尝试使用 [T] 时出现错误。
fn main() {
let mut arr = vec![4,3,2,1];
quick_sort(&mut arr);
println!("{:?}", arr);
}
fn partition<T: Ord>(slice: &mut [T]) -> usize {
let end = slice.len() - 1;
let pivot = slice[end];
let mut j = 0;
for i in 0..end {
if slice[j] <= pivot {
slice.swap(i, j);
j += 1;
}
}
slice.swap(end, j);
j
}
fn quick_sort<T: Ord>(slice: &mut [T]) {
if !slice.is_empty() {
let j = partition(slice);
let len = slice.len();
quick_sort(&mut slice[0..j]);
quick_sort(&mut slice[j+1..len]);
}
}
I get the following error:我收到以下错误:
error[E0508]: cannot move out of type `[T]`, a non-copy slice
--> src/main.rs:9:17
|
9| let pivot = slice[end];
| ^^^^^^^^^^ cannot move out of here
| move occurs because `slice[_]` has type `T`,
| which does not implement the `Copy` trait
| help: consider borrowing here: `&slice[end]`
When let pivot = &slice[end];
当
let pivot = &slice[end];
, I get a different error: ,我得到一个不同的错误:
error[E0308]: mismatched types
--> src/main.rs:12:22
|
7| fn partition<T: Ord>(slice: &mut [T]) -> usize {
| - this type parameter
...
12| if slice[j] <= pivot {
| ^^^^^ expected type parameter `T`, found `&T`
= note: expected type parameter `T`
found reference `&T`
I cannot get this to work with [T].我无法让它与 [T] 一起使用。
We can fix the "expected type parameter T
, found &T
" error by changing the if
to:我们可以通过
if
T
&T
:
if &slice[j] <= pivot {
but that runs into another error:但这会遇到另一个错误:
error[E0502]: cannot borrow `*slice` as mutable because it is also borrowed as immutable
--> src/main.rs:13:13
|
9 | let pivot = &slice[end];
| ----------- immutable borrow occurs here
...
12 | if &slice[j] <= pivot {
| ----- immutable borrow later used here
13 | slice.swap(i, j);
| ^^^^^^^^^^^^^^^^ mutable borrow occurs here
This is because we are taking a reference to a value from the slice and while that reference is alive, we are calling a method that requires mutable access to the slice.这是因为我们正在从切片中获取一个值的引用,并且当该引用处于活动状态时,我们正在调用一个需要对切片进行可变访问的方法。
To fix this, we can inline the referencing into the if
statement itself:为了解决这个问题,我们可以将引用内联到
if
语句本身:
fn partition<T: Ord>(slice: &mut [T]) -> usize {
let end = slice.len() - 1;
let mut j = 0;
for i in 0..end {
if slice[j] <= slice[end] {
slice.swap(i, j);
j += 1;
}
}
slice.swap(end, j);
j
}
Output:输出:
[1, 2, 3, 4]
The reason this worked for [i32]
is because calling slice[end]
implicitly created a copy of the value because i32
implements the Copy
trait.这适用于
[i32]
的原因是因为调用slice[end]
隐式创建了值的副本,因为i32
实现了Copy
trait。 If a type does not implement Copy
, you need to either take a reference using &slice[index]
or if it implements Clone
, call slice[index].clone()
.如果一个类型没有实现
Copy
,您需要使用&slice[index]
进行引用,或者如果它实现了Clone
,则调用slice[index].clone()
。 In this code you have a generic T
which does not implement either of those.在此代码中,您有一个通用
T
不实现其中任何一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.