Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Copy and Clone?

Tags:

rust

People also ask

What is the difference between copy and clone in UVM?

clone method works exactly the same as a copy method, the difference being that a clone will return an object with the copied contents. So this saves some trouble of creating the second object before copy.

What is difference between copy and clone in Rust?

Differs from Copy in that Copy is implicit and extremely inexpensive, while Clone is always explicit and may or may not be expensive. In order to enforce these characteristics, Rust does not allow you to reimplement Copy , but you may reimplement Clone and run arbitrary code.

What is clone and copy in Java?

The Java Object clone() method creates a shallow copy of the object. Here, the shallow copy means it creates a new object and copies all the fields and methods associated with the object. The syntax of the clone() method is: object.clone()

What does it mean to clone a file?

Disk cloning is the process of creating a 1-to-1 copy of a hard disk drive (HDD) or solid-state drive (SSD), not just its files. Disk cloning may be used for upgrading a disk or replacing an aging disk with a fresh one. In this case, the clone can replace the original disk in its host computer.


Clone is designed for arbitrary duplications: a Clone implementation for a type T can do arbitrarily complicated operations required to create a new T. It is a normal trait (other than being in the prelude), and so requires being used like a normal trait, with method calls, etc.

The Copy trait represents values that can be safely duplicated via memcpy: things like reassignments and passing an argument by-value to a function are always memcpys, and so for Copy types, the compiler understands that it doesn't need to consider those a move.


The main difference is that cloning is explicit. Implicit notation means move for a non-Copy type.

// u8 implements Copy
let x: u8 = 123;
let y = x;
// x can still be used
println!("x={}, y={}", x, y);

// Vec<u8> implements Clone, but not Copy
let v: Vec<u8> = vec![1, 2, 3];
let w = v.clone();
//let w = v // This would *move* the value, rendering v unusable.

By the way, every Copy type is also required to be Clone. However, they are not required to do the same thing! For your own types, .clone() can be an arbitrary method of your choice, whereas implicit copying will always trigger a memcpy, not the clone(&self) implementation.


As already covered by other answers:

  • Copy is implicit, inexpensive, and cannot be re-implemented (memcpy).
  • Clone is explicit, may be expensive, and may be re-implement arbitrarily.

What is sometimes missing in the discussion of Copy vs Clone is that it also affects how the compiler uses moves vs automatic copies. For instance:

#[derive(Debug, Clone, Copy)]
pub struct PointCloneAndCopy {
    pub x: f64,
}

#[derive(Debug, Clone)]
pub struct PointCloneOnly {
    pub x: f64,
}

fn test_copy_and_clone() {
    let p1 = PointCloneAndCopy { x: 0. };
    let p2 = p1; // because type has `Copy`, it gets copied automatically.
    println!("{:?} {:?}", p1, p2);
}

fn test_clone_only() {
    let p1 = PointCloneOnly { x: 0. };
    let p2 = p1; // because type has no `Copy`, this is a move instead.
    println!("{:?} {:?}", p1, p2);
}

(Rust Playground)

The first example (PointCloneAndCopy) works fine here because of the implicit copy, but the second example (PointCloneOnly) would error with a use after move:

error[E0382]: borrow of moved value: `p1`
  --> src/lib.rs:20:27
   |
18 |     let p1 = PointCloneOnly { x: 0. };
   |         -- move occurs because `p1` has type `PointCloneOnly`, which does not implement the `Copy` trait
19 |     let p2 = p1;
   |              -- value moved here
20 |     println!("{:?} {:?}", p1, p2);
   |                           ^^ value borrowed here after move

To avoid the implicit move, we could explicitly call let p2 = p1.clone();.

This may raise the question of how to force a move of a type which implements the Copy trait?.

Short answer: You can't / doesn't make sense.