Part 6: Types

Until now every value has had a built-in type — a number, a string, an array, a tuple. This part lets you declare types of your own, shaped to the problem: a Point with an x and a y, a Direction that is one of four, a Command that carries exactly the data its case needs. By the end you can give those types behaviour of their own and pass them around without copying them.

What you will learn

  • Grouping named fields into a struct, and building values with a struct literal.
  • Borrowing a value with &T to read it, and with &var T to change the caller's value in place.
  • Giving a type methods in an extend block, with a self receiver that reads or writes.
  • Building a valid value in one place with a constructor, and adding methods to types you did not write.
  • Naming a fixed set of cases with enum, and choosing the number behind each case.
  • Letting each case carry its own data with variant, and taking it apart with match.
  • Giving a type a second name with type, and storing a function in a field.

How the ideas fit together

flowchart LR
    s["struct<br/>all fields at once"] --> r["&T and &var T<br/>borrow instead of copy"]
    r --> m["extend + self<br/>methods"]
    m --> c["constructors"]
    m --> x["extending types<br/>you did not write"]
    m --> ff["function fields<br/>behaviour as data"]
    e["enum<br/>one of a fixed list"] --> ev["enum values<br/>a number per case"]
    e --> v["variant<br/>one case, with its data"]
    s --> v
    v --> vm["match<br/>take the data out"]
    a["type alias<br/>a second name"]

Structs are the "and" of types — a point has an x and a y. Enums and variants are the "or" — a direction is north or east or south or west. Most programs need both, and the Patterns part that follows is all about taking them apart.

Lessons

LessonWhat you will learn
6.1Structgroup related values into a struct with named fields
6.2Referenceborrow a value with &T instead of copying it
6.3Mutable referencelet a function change the caller's value through &var T
6.4Methodgive a struct behaviour with extend and a self receiver
6.5Mutating methoda method that changes its receiver through self: &var T
6.6Constructorbuild a valid value in one place with a constructor
6.7Extensionadd methods to a type you did not write
6.8Enumname a fixed set of cases
6.9Enum valuegive an enum an explicit underlying type and convert to and from it
6.10Variantattach data to each case
6.11Variant matchtake a variant apart in a match arm
6.12Type aliasgive an existing type a second name to make a signature read clearly
6.13Function fieldstore a function in a struct field and call it later

Before you start

Finish Parts 1–5 first. This part leans most on Part 4: Functions — overloads and callbacks come back as constructors and function fields — and on Part 5: Sequences, whose tuples, arrays and slices appear as fields, receivers and extended types. match from Part 3: Control flow is how enums and variants are read.

Each lesson's package is in the Examples repository's Types/ folder:

cd Examples/Types/Struct
rux run

After this part

Part 7: Patterns shows everything a match arm can say — guards, ranges, tuples and struct patterns — on top of the enums and variants you can now declare. Part 8: Optionals and Part 9: Errors then build on variants' idea of "one of several cases" for values that may be missing and operations that may fail. After Part 9, the checkpoint project Calculator puts a variant to work describing what went wrong.

For the full rules behind this part, see Structures, Methods, Enumerations, Variants with data and Type aliases in the Rux Reference.