How do I define a generic class in EK9?
← Generics · Ref: Q194
EK9 uses natural-language syntax for generics with 'of type T'. Generic classes define type parameters that are filled in when the class is instantiated.
DEFINING A GENERIC CLASS
Use 'of type T' after the class name:
Container of type T item as T?
T is the type parameter that gets replaced with a real type.
CONSTRUCTOR WITH TYPE PARAMETER
Constructors accept T-typed arguments:
Container()
-> val as T
item :=? val
METHODS RETURNING T
Methods can return the type parameter:
get()
<- rtn as T: T()
INSTANTIATION WITH TYPE INFERENCE
The type parameter is inferred from the constructor argument:
strContainer <- Container("hello")
Or explicitly specified:
intContainer <- Container() of Integer
See Q58 for generic functions. See Q93 for class basics. See Q101 for closed by default. See Q195 for type constraints. See Q196 for multi-parameter generics. See Q197 for extending generics. See Q198 for built-in generics.
See Q642 for generic constructor inference. See Q653 for type independence.
Example
defines module qa.generics.classes defines class Container of type T item as T? Container() as pure item :=? T() Container() as pure -> initialItem as T item :=? initialItem get() <- rtn as T: T() rtn :=? T(item) default operator ? defines program GenericClassDemo() stdout <- Stdout() // === INSTANTIATION WITH TYPE INFERENCE === strContainer <- Container("hello") stdout.println(`String container set: ${strContainer?}`) // === EXPLICIT TYPE SPECIFICATION === intContainer <- Container(42) stdout.println(`Integer container set: ${intContainer?}`) // === DEFAULT CONSTRUCTION === emptyContainer <- Container() of String stdout.println(`Empty container set: ${emptyContainer?}`) // === ACCESS VALUE === retrieved <- strContainer.get() if retrieved? stdout.println(`Retrieved: ${retrieved}`)
Common mistakes
E06020 — Container has one type parameter T, so providing two type arguments is wrong. The number of type arguments must match the number of type parameters. See ek9 -h E06020 for details.
Incorrect:
emptyContainer <- Container() of (String, Integer)
Correct:
emptyContainer <- Container() of String
Other ways to ask this
- How do generic types work in EK9?
- How do I create a parameterized class in EK9?
- What is the syntax for generics in EK9?
Coming from another language?
Java: class Container<T> with angle brackets, type erasure at runtime. C++: template<typename T> with full monomorphization. Rust: struct Container<T> with trait bounds. Go: type Container[T any] (Go 1.18+). Kotlin: class Container<T> similar to Java. EK9: 'Container of type T' reads as natural English, type inference from constructors.
Keywords: container, instantiate, parameter, class, define, inference, parameterized, type-parameter, generic, type