How does Rust provide move semantics?

I think it’s a very common issue when coming from C++. In C++ you are doing everything explicitly when it comes to copying and moving. The language was designed around copying and references. With C++11 the ability to “move” stuff was glued onto that system. Rust on the other hand took a fresh start.


Rust doesn’t have constructors at all, let alone move constructors.

You do not need move constructors. Rust moves everything that “does not have a copy constructor”, a.k.a. “does not implement the Copy trait”.

struct A;

fn test() {
    let a = A;
    let b = a;
    let c = a; // error, a is moved
}

Rust’s default constructor is (by convention) simply an associated function called new:

struct A(i32);
impl A {
    fn new() -> A {
        A(5)
    }
}

More complex constructors should have more expressive names. This is the named constructor idiom in C++


No support for rvalue references.

It has always been a requested feature, see RFC issue 998, but most likely you are asking for a different feature: moving stuff to functions:

struct A;

fn move_to(a: A) {
    // a is moved into here, you own it now.
}

fn test() {
    let a = A;
    move_to(a);
    let c = a; // error, a is moved
}

No way to create functions overloads with rvalue parameters.

You can do that with traits.

trait Ref {
    fn test(&self);
}

trait Move {
    fn test(self);
}

struct A;
impl Ref for A {
    fn test(&self) {
        println!("by ref");
    }
}
impl Move for A {
    fn test(self) {
        println!("by value");
    }
}
fn main() {
    let a = A;
    (&a).test(); // prints "by ref"
    a.test(); // prints "by value"
}

Leave a Comment