03 — Generics¶
Generic parameters use square brackets, not angle brackets — this
keeps the syntax unambiguous with comparison operators. In type
position no turbofish is needed (Result[T, E], Option[T]). In
expression position a :: disambiguator separates generic
arguments from index access — see "Turbofish" below.
The program¶
What is interesting¶
fn first[T](...)declares a single generic type parameterT. No constraints —Tmay be any type that fits the body.&[T]is an immutable borrow of a slice ofT. Mighty borrows look like Rust borrows but are written with square brackets for the slice shape.Option[&T]is the built-in optional type fromstd.option. The spec definesOption[T] = Some(T) | None.ifis an expression. Both arms produce a value of typeOption[&T], so the wholeifdoes.&xs[0]borrows the first element without copying it.
Try it¶
Turbofish — expression-position generics¶
In expression position, generic arguments require a :: separator to
disambiguate from index expressions (where Map[k] already means
"index into Map"):
let m = Map::[Str, Json]{} // struct literal with explicit types
let s = Some::[I32](42) // constructor call with type arg
let v = Vec::[T].new() // method call on a generic path
This is documented in docs/spec/v0.1-amendments.md A2. Type-position
generics remain bracket-only as above.
Type errors you might see¶
// MT2004 wrong generic arity
fn f(x: Option[I32, Str]) -> Unit {} // Option takes 1 arg
// Type-arg inference flows from arg to return:
fn id[T](x: T) -> T { x }
let n: I32 = id(42) // T is inferred to I32
let s = id::[Str]("hi") // T is explicit via turbofish
Next¶
Continue to 04 — Errors.