Skip to content

Structs

Apoorv Singal edited this page Aug 30, 2020 · 3 revisions

A struct is a user-defined data type that allows combining data items of different kinds.

Defining a struct type

Struct types are defined using the struct keyword.

struct Name {
    prop1: type1;
    prop2: type2:
    ...
}

Using a struct

struct TestStruct {
    a: u8;
    b: 16;
};
strct: TestStruct; // create an uninitialized TestStruct
strct = (TestStruct){a: 10, b: 20}; // initialize strct

Accessing individual properties

Struct properties are accessed using the dot operator (.). For example, strct.a represents the a property of strct. The dot operator can also be used on struct pointers, i.e, strct.a works even if strct is a pointer to a struct. But the dot operator does not work on a pointer to a pointer to struct. For that, use (*strct).a.

Default struct property values

Struct properties can be given default values when they are defined.

struct TestStruct {
    a: u8 = 100;
};

strct := (TestStruct){};
strct.a; // 100

strct2 := (TestStruct){a: 200};
strct.a; // 200

The default properties are only given when the struct is initialized. A non-initialized struct will have some garbage value even in properties with default values specified.

Methods

Since functions in Volant are expressions, you can use them in structs as,

struct TestStruct {
    function := func () i32 {
        return 0;
    };
};

strct := (TestStruct){};
strct.function(); // 0

While these functions work like methods, they are NOT methods in Volant.

Struct methods should be defined using the function declaration syntax.

struct TestStruct {
    prop := func() {}; // this is an ordinary property
    func method() {}; // this is a struct method
};

There is a very specific reason for this. Since function declarations are constants, there is no need to store them in the structs. Rather, they can be stored globally and all the structs in the program can use the same functions instead of storing their own copy of those functions. Therefore, methods do not take any space at all in structs. Another reason for having struct methods different from ordinary functions is struct inheritance.

Accessing self in methods

If a struct method takes its parent struct or pointer to its parent struct as its first argument, then the call expression, strct.method(...args) automatically becomes strct.method(strct, ...args) internally.

struct TestStruct {
   a: u8 = 100;
   func method1(self: TestStruct) {
       return self.a;
   };
   func method2(self: *TestStruct) {
       return self.a;
   };
};

strct := (TestStruct){};
strct.method1(); // 0
strct.method2(); // 0

Struct Inheritance

Volant allows structs to inherit properties (along with their default values) and methods from other structs using the .. operator.

struct TestStruct {
    prop: u8 = 100;
    func method(self: TestStruct) {
        return self.a;
    };
};

struct TestStruct2 {
    ..TestStruct;
    prop2: u8 = 200;
    func method2(self: TestStruct2) {
        return self.b;
    };
};

strct := (TestStruct2){};

strct.method(); // 100
strct.method2(); // 200

The self argument for the strct.method is automatically changed from TestStruct to TestStruct2.


Structs are allocated on stack by default. See heap for details on how to allocate structs on the heap.

Clone this wiki locally