Structs

In Aptos Move, struct declarations omit public (the type is always nameable from other modules, but fields remain private).

15.1 Declaring and constructing

In Aptos Move, struct declarations omit public (the type is always nameable from other modules, but fields remain private).

// Sui Move 2024: struct visibility required (`public struct`)
public struct Point has copy, drop, store {
    x: u64,
    y: u64,
}

// Positional struct (Move 2024 / Move 2)
public struct Meters(u64) has copy, drop;

public fun origin(): Point { Point { x: 0, y: 0 } }

public fun demo() {
    let p = Point { x: 3, y: 4 };
    let Point { x, y } = p;            // destructure (unpack)
    let m = Meters(10);
    let Meters(inner) = m;
    let q = Point { x, y };            // field punning
    let px = q.x;                      // field access (only inside defining module)
}

15.2 Encapsulation rules

Inside defining module Construct S {.. } Destructure let S {.. } = s Read/write field s.f No (provide getters) Name the type S Pass/return values of S Yes (subject to abilities)

Because only the defining module can create or destroy a struct, the module fully controls the lifecycle of its assets. Expose behavior through functions:

public fun x(p: &Point): u64 { p.x }
public fun set_x(p: &mut Point, v: u64) { p.x = v }

15.3 Nested structs

Structs may contain other structs, vectors, and options but not references and cannot be recursive (a struct cannot contain itself, directly or indirectly).

public struct Profile has key, store {
    id: UID,
    name: String,
    location: Point,
    tags: vector<String>,
    avatar: Option<String>,
}

15.4 Empty structs

Empty structs are common markers: witnesses, capabilities, and type tags.

public struct AdminCap has key, store { id: UID }   // capability (Sui)
public struct Witness has drop {}                   // witness type