【问题标题】:move occurs because value has type Vec<T>, which does not implement the `Copy` traitmove 发生是因为 value 的类型为 Vec<T>,它没有实现 `Copy` 特征
【发布时间】:2020-10-17 01:01:16
【问题描述】:

我正在编写一个非常简单的递归程序来查找两个数之间的所有素数:

use std::cmp::PartialOrd;
use std::ops::{Add, Div, Rem, Sub};

fn _is_prime<T>(n: T, dividend: T, one: T) -> bool
where
    T: Copy + Rem<Output = T> + Sub<Output = T> + PartialOrd,
{
    if dividend == one {
        true
    } else {
        if n % dividend < one {
            false
        } else {
            _is_prime(n, dividend - one, one)
        }
    }
}

fn _primes_between<'a, T>(a: T, b: T, one: T, v: &'a mut Vec<T>) -> &'a mut Vec<T>
where
    T: Copy + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
    if a <= b {
        if _is_prime(a, a - one, one) {
            v.push(a);
        }

        _primes_between(a + one, b, one, v)
    } else {
        v
    }
}

fn primes_between<T>(a: T, b: T) -> Vec<T>
where
    T: Copy + Div<Output = T> + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
    let one = a / a;

    let mut v: Vec<T> = Vec::new();

    *_primes_between(a, b, one, &mut v)
}

fn main() {
    primes_between(3, 13).iter().for_each(|i| println!("{}", i));
}

问题是:

error[E0507]: cannot move out of a mutable reference
  --> src/main.rs:42:5
   |
42 |     *_primes_between(a, b, one, &mut v)
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::vec::Vec<T>`, which does not implement the `Copy` trait

我该如何解决这个错误?

【问题讨论】:

  • 与您的问题无关,但在 Rust 中,_ 前缀对于隐私来说不是必需的,因为有 pub 关键字,因此它获得了“未使用”的含义。经验丰富的 Rustacean 不会将函数命名为 _primes_between_is_prime。除了使用pub,你可以做的另一件事来限制可见性是在其他函数中声明函数,如果它们没有在其他地方使用。

标签: rust


【解决方案1】:

我不是 100% 确定,但我认为问题在于 _primes_between() 返回第 31 行代码试图复制的引用。 (通过使用 * 运算符获得所有权)您可以通过在结果上调用 .clone() 来解决问题,但我认为在这种情况下您不需要 _primes_between() 返回值 - 您只需添加适当的v 参数的条目。类似的东西

fn _primes_between<T>(a: T, b: T, one: T, v: &mut Vec<T>)
where
    T: Copy + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
    if a <= b {
        if _is_prime(a, a - one, one) {
            v.push(a);
        }

        _primes_between(a + one, b, one, v);
    }
}

fn primes_between<T>(a: T, b: T) -> Vec<T>
where
    T: Copy + Div<Output = T> + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
    let one = a / a;

    let mut v: Vec<T> = Vec::new();

    _primes_between(a, b, one, &mut v);

    v
}

【讨论】:

  • 谢谢!那么,如果返回的是一个 Vec,它总是一个“克隆”(深拷贝)?
  • 这里没有克隆或深拷贝。 _primes_between 在原地增长 v 并在 primes_between 返回时移出函数。
  • 明确地说,Rust 通常不会自动进行深度复制。为此,您必须在实现 Clone 特征的结构上调用 clone()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-27
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 2015-11-11
  • 2015-07-15
相关资源
最近更新 更多