patternrustMajor
How does Rust provide move semantics?
Viewed 0 times
howmovesemanticsdoesrustprovide
Problem
The Rust language website claims move semantics as one of the features of the language. But I can't see how move semantics are implemented in Rust.
Rust boxes are the only place where move semantics are used.
The above Rust code can be written in C++ as
As far as I know (correct me if I'm wrong),
How does Rust provide move semantics?
Rust boxes are the only place where move semantics are used.
let x = Box::new(5);
let y: Box = x; // x is 'moved'
The above Rust code can be written in C++ as
auto x = std::make_unique(5);
auto y = std::move(x); // Note the explicit move
As far as I know (correct me if I'm wrong),
- Rust doesn't have constructors at all, let alone move constructors.
- No support for rvalue references.
- No way to create functions overloads with rvalue parameters.
How does Rust provide move semantics?
Solution
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
Rust's default constructor is (by convention) simply an associated function called
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:
No way to create functions overloads with rvalue parameters.
You can do that with traits.
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"
}Code Snippets
struct A;
fn test() {
let a = A;
let b = a;
let c = a; // error, a is moved
}struct A(i32);
impl A {
fn new() -> A {
A(5)
}
}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
}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"
}Context
Stack Overflow Q#29490670, score: 72
Revisions (0)
No revisions yet.