Say I have the following snippet (playground)
struct A {
pub val: u32
}
const GLOBAL_A: A = A {val: 2};
fn main() {
let some_a: A = GLOBAL_A;
let other_a: A = GLOBAL_A;
println!("double val = {}", some_a.val + other_a.val);
}
Since A
is neither Clone
nor Copy
, I would assume the value of GLOBAL_A
would be moved. That does not make much sense for a const and as shown cannot be the case anyways since it can be "moved" twice.
What are the rules that allow the above snippet to work considering A
is not Clone
nor Copy
?
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.
Rust has two different types of constants which can be declared in any scope including global. Both require explicit type annotation: const : An unchangeable value (the common case). static : A possibly mut able variable with 'static lifetime.
Constants are always inlined. Your example is essentially the same as
struct A {
pub val: u32
}
fn main() {
let some_a: A = A {val: 2};
let other_a: A = A {val: 2};
println!("double val = {}", some_a.val + other_a.val);
}
The value is reconstructed twice, so it doesn't need to be Copy
or Clone
.
On the other hand, static
s are not inlined:
struct A {
pub val: u32
}
static GLOBAL_A: A = A {val: 2};
fn main() {
let some_a: A = GLOBAL_A;
}
results in
error[E0507]: cannot move out of static item `GLOBAL_A`
--> src/main.rs:8:21
|
8 | let some_a: A = GLOBAL_A;
| ^^^^^^^^
| |
| move occurs because `GLOBAL_A` has type `A`, which does not implement the `Copy` trait
| help: consider borrowing here: `&GLOBAL_A`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With