Functions & Structs
Functions do things. Structs shape data. Both are deliberately plain, because the interesting machinery in Sure lives elsewhere.
Functions
A function declares its parameters and, if it returns a value, its
return type after ->. A function with a return type must
return on every path — the typechecker verifies this and will tell you
when it can't be sure.
func clamp(n: Int, lo: Int, hi: Int) -> Int {
if n < lo {
return lo
}
if n > hi {
return hi
}
return n
}
func main() -> Int {
print(clamp(140, 0, 100))
return 0
}
Functions without a return type just do their work and stop. Argument counts and types are checked at every call. There is no overloading, no default arguments, and no variadics: a function takes what it takes.
Structs
A struct is named data. Fields are declared with their types; a struct
literal must supply every field by name. There is no partial
initialization, and there is no null to fill the gaps —
a value either exists in full or does not exist.
struct Point {
x: Float,
y: Float,
label: String,
}
func main() -> Int {
let origin = Point { x: 0.0, y: 0.0, label: "origin" }
print(origin.label)
print(origin.x)
return 0
}
Field access uses dots and chains as deep as your data does
(segment.a.x). Fields can be assigned through any binding —
the binding names the struct; the struct's insides remain its own
business:
struct Counter {
hits: Int,
}
func bump(c: Counter) {
c.hits = c.hits + 1
}
func main() -> Int {
let c = Counter { hits: 0 }
bump(c)
bump(c)
print(c.hits) // 2 — c names the same struct everywhere
return 0
}
Structs are references
That last example worked because struct values live on the heap and
variables hold references to them. Passing a struct to a function passes
the reference; no copy is made. The same is true of strings, arrays,
maps, and channels. The four basic types — Int,
Float, Bool — travel by value.
Heap values are the ones whose lifetimes must end somewhere. Where, exactly, is the subject of chapter 7; for now it is enough to know that when a struct is deleted, everything it owns — its strings, its structs, their strings — is deleted with it, recursively, in declaration order.
struct Node { next: Node, } with struct 'Node'
contains itself. If you need linked structures, use an array; if
you need a tree, a struct may contain an array of its own type,
which is permitted because an array can be empty and a recursion can
therefore end.