Part 12: Interfaces
A circle and a rectangle both have an area; a price and a temperature can both be printed; a version number and a score can both be put in order. An interface names a piece of behaviour like that, and any type can promise to provide it. This part shows how to declare and keep such a promise, how code written against the promise works for every type that keeps it, and how your own types join in with the language's own machinery: {} placeholders, == and <, square brackets and for loops.
What you will learn
- Declaring an
interfaceand implementing it withextend Type : Interface. - Interface values: one variable, array or loop holding many types, with dynamic dispatch choosing the method.
- Interface parameters,
&Iand&var I, and requirements that write withself: &var Self. - The standard interfaces
Display,EquatableandComparable, and theOrderinga comparison answers with. - Comparing structs, tuples, arrays and variants with
==, field by field, for free. - Declaring operators such as
+,==,<and[]for your own types, and the four comparisons derived from two. - Making a type walkable by
forwithNext, and a collection withIterate.
How a type joins in
flowchart LR
t(["Your type"]) --> own["interface + extend T : I<br/>a promise the compiler checks<br/>(12.1)"]
own --> dyn["interface values and parameters<br/>one call, many types<br/>(12.2–12.3)"]
t --> std["standard interfaces<br/>printed with {}, Equals, Compare<br/>(12.4–12.6)"]
t --> ops["operator functions<br/>==, +, <, []<br/>(12.7–12.10)"]
t --> loops["Next and Iterate<br/>walked by for<br/>(12.11–12.12)"]Lessons
| Lesson | What you will learn | |
|---|---|---|
| 12.1 | Interface | declare an interface and implement it for your own types |
| 12.2 | Interface value | hold any implementing type in one interface value |
| 12.3 | Interface parameter | write a function that accepts any type implementing an interface |
| 12.4 | Display | make your own type printable with {} |
| 12.5 | Equatable | define what it means for two of your values to be equal |
| 12.6 | Comparable | define an order for your own type |
| 12.7 | Structural equality | compare whole structs and tuples with == |
| 12.8 | Operator overload | define ==, + and the other operators for your own type |
| 12.9 | Derived operator | define one operator and get its partners for free |
| 12.10 | Indexer | let your own type be indexed with [] |
| 12.11 | Iterator | implement Next so a type of your own can be used with for |
| 12.12 | Iterable | let a container hand out an iterator for for |
Before you start
Finish Part 11: Ownership — an interface value is a copy of what it holds. The lessons also lean on Method, Extension and Mutable reference from Part 6, on optionals from Part 8 for iterators, and on Propagate from Part 9 for Display. Each lesson's package is in the Examples repository's Interfaces/ folder:
cd Examples/Interfaces/Interface
rux run
After this part
Part 13: Generics writes one function or type for many types at once, and interfaces come straight back as its bounds: <T: Display> accepts any type that keeps the Display promise, checked when the program is compiled rather than dispatched while it runs. After Part 16: Numbers you are ready for the next checkpoint projects, Circle and Quadratic.
For the rules behind this part, see Interfaces, Methods and Comparison operators in the Rux Reference.