Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Generics

A generic declaration takes parameters in angle brackets, so one declaration covers a whole family of types or macros. bits<8> and bits<32> are two types made from one generic struct, bits<const width: int>.

Two kinds of parameter

KindWrittenStands forExample
Type parameterTa typePair<T>, used as Pair<int>
Const parameterconst N: inta value known at compile timebits<const width: int>, used as bits<8>

Structs, enums, type aliases and macros can all be generic.

Generic structs

struct Pair<T> {
    pub a: T,
    pub b: T,
}

macro emit_pair(p: Pair<int>) {
    @emit p
}

emit_pair Pair<int> { a: 1, b: 2 }
Pair<int> { a: 1, b: 2 }

A generic struct is constructed with braces, naming its arguments: Pair<int> { ... }. The Name(...) form is only for non-generic structs.

Generic enums work the same way. See Enums.

Generic macros

A generic macro’s parameters are inferred from its arguments. You never write them at the call:

struct Pair<T> {
    pub a: T,
    pub b: T,
}

macro first<T>(p: Pair<T>) -> T {
    @return p.a
}

macro show(value: int) {
    @emit value
}

show first(Pair<int> { a: 5, b: 6 })
5

Inside the macro, a const parameter is an ordinary value, and a type parameter can be used anywhere a type can.

A generic overload loses to a non-generic one that also fits. See Overloading.

In this chapter