Skip to content
FutureBlitz

    Install

    Your own types, 1 of 8

    Structs

    Group fields into a value type with its own constructor and Methods, and see how it's copied.

    What you’ll build

    A Point type for a drawing program: a pair of coordinates with Methods to measure and move it. A Struct is the right kind of type for it, since a point is a small value, like a number, that is copied rather than shared.

    Declaring a Struct

    A Struct lists its fields with Field, each with its type and maybe a default. A Struct gets a constructor that takes its fields in order, unless it declares a New of its own. Like any call, it takes named arguments too. A field the call leaves out gets its default, or its type’s zero when it has none.

    point.fb
    Import std.core
    
    Struct Point
        Field X: Float
        Field Y: Float = 0.0
    End Struct
    
    Local a = Point(3.0, 4.0)
    Local b = Point(Y: 2.0, X: 1.0)
    Local c = Point(5.0)
    Print(a.X, a.Y, b.Y, c.Y)
    Print("{a:?}")
    Output
    3 4 2 0
    Point { X: 3, Y: 4 }

    {a:?} shows any value in its debug form, with each field’s name and value.

    Methods

    A Method is a function that belongs to the type. Inside it, the fields are used by name. A Struct’s Methods only read its fields; a ByRef Method can change them, and can only be called on a variable, whose value it changes in place.

    point.fb
    Import std.core
    Import std.math
    
    Struct Point
        Field X: Float
        Field Y: Float
    
        Method Length(): Float => Sqrt(X * X + Y * Y)
    
        ByRef Method Move(dx: Float, dy: Float)
            X += dx
            Y += dy
        End Method
    End Struct
    
    Local p = Point(3.0, 4.0)
    Print(p.Length())
    p.Move(1.0, -1.0)
    Print(p.X, p.Y)
    Output
    5
    4 3

    Sqrt is from std.math.

    Copies

    A Struct is a value: assigning it, passing it to a function, or storing it in an array makes a copy. Changing the copy leaves the original as it was. == compares two Structs field by field.

    point.fb
    Import std.core
    
    Struct Point
        Field X: Float
        Field Y: Float
    
        ByRef Method Move(dx: Float, dy: Float)
            X += dx
            Y += dy
        End Method
    End Struct
    
    Local start = Point(0.0, 0.0)
    Local finish = start
    finish.Move(5.0, 2.0)
    Print("{start:?} {finish:?}")
    Print(start == Point(0.0, 0.0), start == finish)
    Output
    Point { X: 0, Y: 0 } Point { X: 5, Y: 2 }
    True False

    Since an array’s elements can move when it grows, a ByRef Method can’t be called on one in place: points[0].Move(1.0, 1.0) is an error. Copy the element into a Local, change it, and store it back.

    Printing a Struct

    Print and "{p}" show a value through its ToString Method, which a type gives by implementing std.core’s Printable Interface. Without one, printing a Struct doesn’t build, and fb says what to add; the debug form, {p:?}, always works.

    point.fb
    Import std.core
    
    Struct Point
        Field X: Float
        Field Y: Float
    End Struct
    
    Print(Point(1.5, 2.0))
    $ fb run point.fb
       Compiling point.fb
    point.fb:8:7: error: Point can't be shown by 'Print'; implement Printable, with a ToString
      |
    8 | Print(Point(1.5, 2.0))
      |       ^^^^^^^^^^^^^^^
    error: couldn't build point.fb because of 1 error

    With Implements Printable and a ToString, it prints:

    point.fb
    Import std.core
    
    Struct Point Implements Printable
        Field X: Float
        Field Y: Float
    
        Method ToString(): String => "({X}, {Y})"
    End Struct
    
    Local path = [Point(0.0, 0.0), Point(1.5, 2.0), Point(3.0, 0.5)]
    Print(path[1])
    Print(path)
    Output
    (1.5, 2)
    [(0, 0), (1.5, 2), (3, 0.5)]

    What you learned

    • A Struct is a value type made of fields, with a constructor that takes them in order; a field left out gets its default or its zero.
    • Methods read the fields by name; a ByRef Method changes them in place.
    • Assigning a Struct copies it, and == compares its fields.
    • Implements Printable and a ToString Method let a Struct be printed.

    Report an issue with this page or with FutureBlitz on GitHub.