Your own types, 8 of 8
Extend
Add Methods to any type, the built-in ones included, and make an existing type implement an Interface.
What you’ll build
A few helpers that read as if they were part of the language: "level".IsPalindrome(),
3.Times(...), and scores.Second(). Then a Struct that becomes printable without changing its
declaration. An Extend block adds Methods to a type that’s already declared, anywhere, even a
built-in type or std’s.
Methods for String and Int
Extend String adds Methods to every String. Inside them, Self is the value, and the type’s own
members are used by name, as in the type’s own Methods.
Import std.core
Import std.text
Extend String
Method Shout(): String => ToUpper() + "!"
Method IsPalindrome(): Bool
Local letters = ToLower().Chars
For i = 0 Until letters.Count / 2
If letters[i] != letters[letters.Count - 1 - i] Then Return False
End For
Return True
End Method
End Extend
Extend Int
Method IsEven(): Bool => Self % 2 == 0
Method Times(action: Func(Int))
For i = 1 To Self
action(i)
End For
End Method
End Extend
Print("hello".Shout())
Print("Level".IsPalindrome(), "Hello".IsPalindrome())
Print(4.IsEven(), 7.IsEven())
3.Times(Function(i) => Print("pass {i}"))HELLO! True False True False pass 1 pass 2 pass 3
Methods for every array
Extend T[] adds Methods to arrays of every type, with T standing for the element type. Here
Second gives the second element, or Null for an array of fewer than two.
Import std.core
Extend T[]
Method Second(): T? => Count > 1 ? Self[1] : Null
End Extend
Print([10, 20, 30].Second() ?? 0)
Print(["only"].Second() ?? "none")20 none
Implementing an Interface
Extend Point Implements Printable makes Point implement Printable, with the Methods the
Extend gives, so a Point can be printed. This works on types from other files and packages too,
whose declarations you can’t change.
Import std.core
Struct Point
Field X: Int
Field Y: Int
End Struct
Extend Point Implements Printable
Method ToString(): String => "({X}, {Y})"
End Extend
Local corners = [Point(0, 0), Point(4, 0), Point(4, 3)]
Print(corners)[(0, 0), (4, 0), (4, 3)]
An Extend adds behavior, never data: it can’t add fields or a New, since how a type is stored
and made is the type’s own. Its Methods can’t replace one the type has, and aren’t virtual, so
nothing overrides them. An Extend’s Methods are seen only in its own module and where that module
is imported, so one file’s helpers don’t change what another file’s code means. The Interfaces an
Extend adds are different: they hold everywhere, since a type is Printable or isn’t, for the whole
program.
What you learned
Extend Tadds Methods to an existing type, built-in types included.- Inside an Extend,
Selfis the value, and the type’s members are used by name. Extend T[]adds Methods to every array, withTas the element type.Extend T Implements Imakes an existing type implement an Interface.- An Extend adds no fields or
New, and replaces nothing the type has.
The rules are in the language reference.
Report an issue with this page or with FutureBlitz on GitHub.