Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

rust - What do I have to do to solve a "use of moved value" error?

I'm trying to compute the 10,001st prime in Rust (Project Euler 7), and as a part of this, my method to check whether or not an integer is prime references a vector:

fn main() {
    let mut count: u32 = 1;
    let mut num: u64 = 1;
    let mut primes: Vec<u64> = Vec::new();
    primes.push(2);

    while count < 10001 {
        num += 2;
        if vectorIsPrime(num, primes) {
            count += 1;
            primes.push(num);
        }
    }
}

fn vectorIsPrime(num: u64, p: Vec<u64>) -> bool {
    for i in p {
        if num > i && num % i != 0 {
            return false;
        }
    }

    true
}

When I try to reference the vector, I get the following error:

error[E0382]: use of moved value: `primes`
 --> src/main.rs:9:31
  |
9 |         if vectorIsPrime(num, primes) {
  |                               ^^^^^^ value moved here, in previous iteration of loop
  |
  = note: move occurs because `primes` has type `std::vec::Vec<u64>`, which does not implement the `Copy` trait

What do I have to do to primes in order to be able to access it within the vectorIsPrime function?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

With the current definition of your function vectorIsPrime(), the function specifies that it requires ownership of the parameter because you pass it by value.

When a function requires a parameter by value, the compiler will check if the value can be copied by checking if it implements the trait Copy.

  • If it does, the value is copied (with a memcpy) and given to the function, and you can still continue to use your original value.
  • If it doesn't, then the value is moved to the given function, and the caller cannot use it afterwards

That is the meaning of the error message you have.

However, most functions do not require ownership of the parameters: they can work on "borrowed references", which means they do not actually own the value (and cannot for example put it in a container or destroy it).

fn main() {
    let mut count: u32 = 1;
    let mut num: u64 = 1;
    let mut primes: Vec<u64> = Vec::new();
    primes.push(2);

    while count < 10001 {
        num += 2;
        if vector_is_prime(num, &primes) {
            count += 1;
            primes.push(num);
        }
    }
}

fn vector_is_prime(num: u64, p: &[u64]) -> bool {
    for &i in p {
        if num > i && num % i != 0 {
            return false;
        }
    }
    true
}

The function vector_is_prime() now specifies that it only needs a slice, i.e. a borrowed pointer to an array (including its size) that you can obtain from a vector using the borrow operator &.

For more information about ownership, I invite you to read the part of the book dealing with ownership.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...