Structs

Structs in Zard are composite types used to group related data. They can contain primitives, lists, or other structs recursively.

Declaring a Struct


Struct Pessoa {
    string nome;
    int idade;
}

Nested Structs


Struct Endereco {
    string rua;
    string cidade;
    Struct Pais pais;
}

Assigning Values


Pessoa p;

p.nome = "Alice";
p.idade = 22;

Struct inside Struct


Endereco e;

e.rua = "Rua Central";
e.cidade = "São Paulo";

Pais brasil;
brasil.nome = "Brasil";

e.pais = brasil;

List of Structs


List pessoas;

pessoas.add(p);

Impl: Methods for Structs

The impl block allows attaching functions directly to a struct. This lets structs contain both data and behavior.

The s Self Reference

Inside an impl block, Zard provides a reserved variable called s.


impl Pessoa {

    function void hello() {
        print("Hello from:");
        print(s.nome);
    }

}

Basic Impl Example


Struct Pessoa {
    string nome;
    int idade;
}

impl Pessoa {

    function void hello() {
        print("Olá do método hello()");
    }

}

Pessoa p;

p.nome = "Zard";
p.idade = 22;

p.hello();

Returning the Struct (Method Chaining)

Returning the struct itself enables method chaining.


impl Pessoa {

    function Pessoa setName(string n) {
        s.nome = n;
        return s;
    }

}

Pessoa p;

p.setName("Lucas")
p.setName("Ana");

Inline Struct Update

Zard allows updating struct fields using an inline update block. This syntax lets you modify multiple fields of a struct (including nested structs) in a single expression.

This feature is particularly useful for updating deeply nested structures without writing many individual assignments.

Example


p2.endereco {
    rua: "Nova Rua";
    cidade: "Zurique";
    pais {
        nome: "Suíça";
    }
}

The block above updates the fields of p2.endereco.

Equivalent Manual Code

Without the inline update syntax, the same operation would require multiple assignments:


p2.endereco.rua = "Nova Rua";
p2.endereco.cidade = "Zurique";
p2.endereco.pais.nome = "Suíça";

Complete Example


main {

    Struct Pais {
        string nome;
    }

    Struct Endereco {
        string rua;
        string cidade;
        Struct Pais pais;
    }

    Struct Pessoa {
        string nome;
        int idade;
        Struct Endereco endereco;
        List telefones;
    }

    Pais brasil;
    brasil.nome = "Brasil";

    Endereco e1;
    e1.rua = "Rua A";
    e1.cidade = "São Paulo";
    e1.pais = brasil;

    Pessoa p1;
    p1.nome = "Alice";
    p1.idade = 25;
    p1.endereco = e1;

    p1.telefones.add("11 99999-1111");
    p1.telefones.add("11 22222-3333");


    Pessoa p2;
    p2 = p1;


    p2.nome = "Zard";
    p2.telefones.add("21 44444-5555");


    print("=== Original p1 ===");
    print(p1);


    p2.endereco {
        rua: "Nova Rua";
        cidade: "Zurique";
        pais {
            nome: "Suíça";
        }
    }

    print("=== Clone p2 ===");
    print(p2);

}

Why This Feature Exists


Structs With Only Methods

In Zard, a struct does not need to contain fields. It may exist purely to group related functions.

This allows structs to act as method containers, similar to utility classes or namespaces in other languages.


main {

    Struct Math {}

    impl Math {

        function int sum(int x, int z){
            return x + z;
        }

    }

    Math m;

    println(m.sum(2,3));

}

In this example:

This pattern is useful for organizing reusable functions that conceptually belong together.