简体   繁体   English

由于 `slice[_]` 的类型为 `T`,它没有实现 `Copy` 特征,因此无法移出此处发生移动

[英]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]

Playground 操场


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.

相关问题 移动发生是因为值的类型为 Vec<T> ,它没有实现 `Copy` 特性 - move occurs because value has type Vec<T>, which does not implement the `Copy` trait move 发生是因为 value 的类型为 `RefCell&lt;…&gt;`,它没有实现 `Copy` 特征 - move occurs because value has type `RefCell<…>`, which does not implement the `Copy` trait Rust:发生移动是因为类型为 `ReadDir`,它没有实现 `Copy` 特征 - Rust: move occurs because has type `ReadDir`, which does not implement the `Copy` trait 如何避免“由于`v`的类型为`Vec而发生移动<char> `,它没有在循环中实现`Copy` trait&quot; - How to avoid "move occurs because `v` has type `Vec<char>`, which does not implement the `Copy` trait" within loop 发生 Rust 文件树移动是因为 `subtree` 的类型为 `trees::Tree<PathBuf> `,它没有实现 `Copy` 特征 - Rust File Tree move occurs because `subtree` has type `trees::Tree<PathBuf>`, which does not implement the `Copy` trait 无法移出位于共享引用移动后面的 `*handle`,因为 `*handle` 具有类型 - cannot move out of `*handle` which is behind a shared reference move occurs because `*handle` has type 在匹配中分配向量的值:移动发生......它没有实现“复制”特征 - Assigning value of vector inside match: move occurs … which does not implement the `Copy` trait &#39;移动发生是因为值具有类型&#39; Rust 错误 - 'move occurs because value has type' Rust error 如何强制执行实现复制特征的类型的移动? - How to force a move of a type which implements the Copy trait? Rust 编译错误:'发生移动是因为 `self.styles` 的类型为 `HashMap&lt;&amp;str, &amp;str&gt;`' - Rust compilation error: 'move occurs because `self.styles` has type `HashMap<&str, &str>`'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM