Generics
19.1 Generic Functions
Since V 0.4, generics use square brackets [T]. Older code used <T>.
fn max_of[T](a T, b T) T {
return if a > b { a } else { b }
}
fn find[T](arr []T, x T) ?int {
for i, v in arr {
if v == x { return i }
}
return none
}
println(max_of(3, 7))
println(max_of('a', 'b'))
println(max_of[f64](1.5, 2.5)) // explicit type argument
println(find([1, 2, 3], 2) or { -1 })19.2 Generic Structs
struct Stack[T] {
mut:
items []T
}
fn (mut s Stack[T]) push(x T) { s.items << x }
fn (mut s Stack[T]) pop() ?T {
if s.items.len == 0 { return none }
return s.items.pop()
}
fn (s Stack[T]) is_empty() bool { return s.items.len == 0 }
mut st := Stack[int]{}
st.push(1)
st.push(2)
println(st.pop() or { 0 })
struct Pair[K, V] {
key K
val V
}
p := Pair[string, int]{'age', 30}19.3 Generic Constraints and Compile-Time Checks
Interfaces can act as constraints (pass the interface type). Comptime $if T is ... handles type-specific paths.
fn sum[T](nums []T) T {
mut total := T(0)
for n in nums { total += n }
return total
}
fn describe[T](x T) string {
$if T is int { return 'int' }
$else $if T is string { return 'string' }
$else $if T is $struct { return 'struct ${T.name}' }
return 'other'
}