Structs

Struct declarations, literals, methods, implemented interfaces, and field access.

Structs define named fields and may implement interfaces.

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 10, y: 20 };
    _ = p.x + p.y;
}

Methods and Interfaces

interface Movable {
    fn move(self, dx: i32, dy: i32);
}

struct Cursor : Movable {
    x: i32,
    y: i32,

    fn move(self, dx: i32, dy: i32) {
        self.x += dx;
        self.y += dy;
    }
}

Struct literal fields are checked for presence, spelling, and type. Interface implementations are checked against required fields, methods, inherited interfaces, and default method signatures.

A method whose first parameter is self is an instance method. A method without a first self parameter is a static method and is called through the type or a module-qualified type expression.

struct Limits {
    fn max() -> i32 {
        return 100;
    }
}

fn main() {
    assert Limits.max() == 100;
}

For a fuller guide to capability interfaces and generic bounds, see Interfaces. For overloaded methods and constructors, see Function Overloading.

Initializers

Structs can declare init methods. Constructor calls use matching init overloads.

struct Buffer {
    size: usize,

    init(self) {
        self.size = 0;
    }

    init(self, size: usize) {
        self.size = size;
    }
}

fn main() {
    let empty = Buffer();
    let sized = Buffer(16);

    assert empty.size == 0;
    assert sized.size == 16;
}

Initializers may return void or void throws(ErrorSet). A fallible initializer makes the constructor call fallible:

error InitError {
    Empty
}

struct Named {
    value: str,

    init(self, value: str) throws(InitError) -> void {
        if value == "" {
            throw InitError.Empty;
        }
        self.value = value;
    }
}

fn main() {
    let named = try Named("zynx");
    assert named.value == "zynx";
}

Non-void initializer return types are rejected.

Destructors

Structs can declare a drop(self) destructor to release resources when an owning value is cleaned up.

import std.os;

struct Tracer {
    id: i32,

    drop(self) {
        _ = os.write("drop {self.id}\n");
    }
}

fn main() {
    let tracer = Tracer { id: 1 };
    _ = tracer.id;
}

drop(self) is a special struct member. It has no fn keyword and no return type. A struct with drop cannot implement Copy.

See RAII and Drop for cleanup order, manual std.drop, defer, and with.