Structs

    Structs inherit from Value so they are allocated on the stack and passed by value: when passed to methods, returned from methods or assigned to variables, a copy of the value is actually passed (while classes inherit from , are allocated on the heap and passed by reference).

    Therefore structs are mostly useful for immutable data types and/or stateless wrappers of other types, usually for performance reasons to avoid lots of small memory allocations when passing small copies might be more efficient (for more details, see the performance guide).

    Mutable structs are still allowed, but you should be careful when writing code involving mutability if you want to avoid surprises that are described below.

    Notice that the chained calls of plus return the expected result, but only the first call to it modifies the variable counter, as the second call operates on the copy of the struct passed to it from the first call, and this copy is discarded after the expression is executed.

    You should also be careful when working on mutable types inside of the struct:

    What happens with the strukt here:

    • Array is passed by reference, so the reference to ["str"] is stored in the property of strukt
    • the array referenced by array is modified (element inside it is added) by object.array << "foo"
    • this is also reflected in the original strukt as it holds reference to the same array
    • object.array = ["new"] replaces the reference in the copy of strukt with the reference to the new array
    • returns the reference to this new array and its content is printed
    • the reference to this new array was held only in the copy of strukt, but not in the original, so that’s why the original strukt only retained the result of the first statement, but not of the other two statements

    Inheritance

    • A struct implicitly inherits from Struct, which inherits from . A class implicitly inherits from Reference.

    The second point has a reason to it: a struct has a very well defined memory layout. For example, the above Point struct occupies 8 bytes. If you have an array of points the points are embedded inside the array’s buffer:

    If is inherited, an array of such type should also account for the fact that other types can be inside it, so the size of each element should grow to accommodate that. That is certainly unexpected. So, non-abstract structs can’t be inherited from. Abstract structs, on the other hand, will have descendants, so it is expected that an array of them will account for the possibility of having multiple types inside it.

    A struct can also include modules and can be generic, just like a class.