Andree Wijaya
Andree Wijaya

Reputation: 425

Why can I still use a variable after transferring ownership of it into a function?

I'm trying to pick up the pieces in Rust on the "borrowing" concept. Below is my code but I'm unable to get any borrowing error. From my understanding prime1's ownership has been transferred but I can still use print on the variable.

fn main() {
    let prime1 = 100;
    all_prime_to(prime1);
    
    println!("{}", prime1);
}


fn prime_checker(num: u32) -> bool {
    let mut counter = 0;
    for x in 1..num {
       if num % x == 0 {
           counter += 1;
       }
    }

    counter < 2
}

// Vec is the same as arraylist in JAVA
fn all_prime_to(num: u32) -> Vec<u32> {
    let capacity = (num/3) as usize;
    let mut vec = Vec::with_capacity(capacity);

    for x in 2..num {
       if prime_checker(x){
           vec.push(x)
       }
    }

    vec
} 

When I use the referencing method to keep the ownership of prime1, it still gives the same output.

Upvotes: 1

Views: 504

Answers (2)

prog-fh
prog-fh

Reputation: 16920

In the following example, you can see that some primitive types (i32 here) are implicitly copied when they are passed by value.

Some other more elaborate types (String here) can be explicitly cloned which can help keep the original value when passed by value.

When it comes to your own types, you have to decide whether it makes sense or not to implement Clone and why not Copy. Copy is supposed to be a cheap operation (like for i32) that could happen implicitly without introducing too much overhead. On the other hand, Clone applies to types for which it makes sense to obtain a new identical value but this operation might introduce a sensible overhead (dynamic memory allocation for example), thus an explicit call to clone() makes clear that this was intentional.

fn consume_i32(arg: i32) {
    println!("consuming {}", arg);
}

fn consume_string(arg: String) {
    println!("consuming {}", arg);
}

fn main() {
    let v0 = 123;
    consume_i32(v0);
    println!("{} still available", v0);
    println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    let v1 = String::from("hello");
    consume_string(v1);
    // next line won't compile --> commented out
    // println!("{} still available", v1);
    println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    let v2 = String::from("again");
    consume_string(v2.clone());
    println!("{} still available", v2);
}

Upvotes: 4

John Kugelman
John Kugelman

Reputation: 362137

u32 is Copy which means it is copied instead of moved.

Upvotes: 3

Related Questions