On move, copy and deref

Few more.

  1. When do I need keyword move? I know that when I pass primitive type as function argument it’s being copied and still exist in current scope, when I pass complex types (struct or vector) they’re being moved. That being said, I can only imagine using move to explicitly move primitive value to another scope (though is there a reason to do so?).

  2. How does dereferencing work? I remember in one of my experiments I successfully recreated object from mutable reference in another scope by using deref. Is it actually copying original value? Is pricey in terms of gas? Should I avoid unnecessary dereferencing?

  3. Follow up on question 2: if I can copy though deref, are there cases where explicit copy is the only possible way of achieving smth?

@todd @drussi

You likely never need to explicitly annotate a move except in the case where you want to explicitly move an implicitly copyable (i.e. primitive) value.
Behavior around copy/move is inferred by the compiler. You could imagine some situation down the road where the compiler might not be able to infer the correct operation. This might happen in the future if we change the language (either by adding new features or changing existing rules)

Dereferencing * is an operation that takes a reference &t and gives back a copy of the data of type t at that memory location. So yes, it is fully copying the underlying value. You should avoid unnecessary dereferencing for large data.

For primitives/implicitly copyable data, its probably a toss up and likely not worth fretting over. This is why there is convenient syntax for that case. If you have struct S { f: u64 } and s: &S, let x = s.f implicitly copies. In short s.f is sugar for *&s.f

Yes, any non implicitly copyable type has to be copied via a copy or *, otherwise it is a move

For example:

struct S { f: u64 }
let v: vector<u64> = ...:
let s: S = S { f : 0 };
let x = v; // Implicit move 
let x = s; // Implicit move
let x = copy v; // Ok
let x = *&v; // Ok
let x = copy s; // Ok
let x = *&s; // Ok

also it’s probably clear to you but whether a type is a resource or a copyable value affects the move/copy semantic.
Resources cannot be copied ever.
Dereference is always a copy.
Given the above you cannot ever dereference a resource inside a struct (or a resource you have a reference on).
Resource cannot be overwritten.
So you cannot write to a resource reference ever.
There are few more implications of the above obviously, particularly in the way you can manage structures which I am not going in but should be derivable.

1 Like