Move

Structs

struct Foo {
  x: u64,
  y: bool
}

In Move, modules have much more control over how their types can and can’t be used than conventional programming languages do. A struct defined as in the code snippet above will have the following restrictions:

  • It can only be instantiated (“packed”) and destroyed (“unpacked”) inside the module that defines the struct — i.e. you cannot instantiate or destroy a struct instance from inside any function in any other module

  • Fields of a struct instance can only be accessed (and therefore mutated) from its module

  • You cannot clone or duplicate a struct instance outside its module

  • You cannot store a struct instance in a field of some other struct instance

This means that if you’re handling an instance of this struct in a function in another module, you wouldn’t be able to mutate its fields, clone it, store it in a field in another struct, or drop it (you’d have to pass it on somewhere else via a function call). It may be the case that the struct’s module implements functions that do those things that can be called from our module, but otherwise we can’t do any of those things directly for an external type. This gives modules full control over how their types can and can’t be used.

Move allows us to loosen up some of these restrictions by adding capabilities to structs. There are four capabilities: key, store, copy, and drop. You can add any combination of these capabilities to a struct:

struct Foo has key, store, copy, drop {
  id: UID,
  x: u64,
  y: bool
}
  • key — this allows a struct to become an object (Sui specific, core Move is slightly different). As explained earlier, objects are persisted and, in the case of owned objects, require user signatures to be used in a smart contract call. When the key capability is used, the first field of the struct must be the ID of the object with the type UID. This will give it a globally unique ID that can be used to reference it.

  • store — this allows the struct to be embedded as a field in another struct

  • copy — this allows the struct to be copied/cloned arbitrarily from anywhere

  • drop — this allows the struct to be destroyed arbitrarily from anywhere

In essence, every struct in Move is a resource by default. Capabilities give us the power to granularly loosen up these restrictions and make them behave more like conventional structs.

Last updated