Pular para o conteúdo

Genéricos

Nesta página

Funções genéricas recebem um ou mais parâmetros de tipo entre <>. O compilador infere T a partir dos argumentos na chamada — não é preciso especificar o tipo explicitamente. Funções com múltiplos parâmetros de tipo (<A, B>) preservam cada tipo de forma independente:

identity<T>, head<T> e pair_first<A, B> funcionam com int, str, bool e arrays.

10-generic-fn.zolo
Playground
// Feature: Generic functions

// Syntax: `fn name<T>(x: T) -> T { ... }`

// When to use: logic that works with ANY type (identity, containers,

// swaps) preserving the concrete type through the return value.


// Identity — `T` is inferred at the call site.

fn identity<T>(x: T) -> T {
  return x
}

print(identity(42))  // 42

print(identity("hi"))  // hi

print(identity(true))  // true


// More than one arg of the same `T`.

fn first<T>(a: T, b: T) -> T {
  return a
}

print(first(1, 2))  // 1

print(first("a", "b"))  // a


// Generic with array.

fn head<T>(arr: [T]) -> T {
  return arr[0]
}

print(head([10, 20, 30]))  // 10

print(head(["x", "y"]))  // x


// Multiple type params.

fn pair_first<A, B>(a: A, b: B) -> A {
  return a
}

print(pair_first(7, "right-side"))  // 7

// expected:

// 42

// hi

// true

// 1

// a

// 10

// x

// 7

Structs genéricos armazenam qualquer tipo sem perder a informação de qual é. O tipo concreto é inferido do literal de construção. O bloco impl de um struct genérico acompanha o parâmetro de tipo:

Box<T>, Pair<A, B> e Stack<T> com impl Stack incluindo método associado e de instância.

11-generic-struct.zolo
Playground
// Feature: Generic structs

// Syntax: `struct Name<T> { field: T }`

// When to use: container that holds any type while preserving it.


struct Box<T> {
  value: T,
}

// Concrete type comes from usage.

let bi = Box { value: 42 }  // Box<int>

let bs = Box { value: "hello" }  // Box<str>

print(bi.value)  // 42

print(bs.value)  // hello


// Multiple type parameters.

struct Pair<A, B> {
  first: A,
  second: B,
}

let p = Pair { first: 1, second: "one" }
print(p.first)  // 1

print(p.second)  // one


// `impl` for generic struct — the `<T>` is inferred from the type name.

// NOTE: `len` is dispatched at the runtime level for Array/Map, so we

// expose the size under a distinct name (`size`) to avoid the clash.

struct Stack<T> {
  items: [T],
}

impl Stack {
  fn make() -> Stack {
    return Stack { items: [] }
  }

  fn size(self) -> int {
    return self.items.len()
  }
}

let s = Stack::make()
print(s.size())  // 0

Enums genéricos são a base de tipos somados parametrizados — o mesmo mecanismo que a stdlib usa para Option<T> e Result<T, E>. O match desestrutura o payload e liga a variável ao tipo concreto:

Maybe<T> com variantes Just(T) e Nothing; Either<L, R> com dois parâmetros.

12-generic-enum.zolo
Playground
// Feature: Generic enums

// Syntax: `enum Name<T> { Variant(T), Other }`

// When to use: parameterized sum types — this is how the stdlib

// defines `Option<T>` and `Result<T, E>`.


enum Maybe<T> {
  Just(T),
  Nothing,
}

// Construction: the `T` type comes from the payload.

let just_int = Maybe.Just(42)
let just_str = Maybe.Just("hello")
let none: Maybe<int> = Maybe.Nothing

let r1 = match just_int {
  Maybe::Just(v) => "got {v}",
  Maybe::Nothing => "none",
}
print(r1)  // got 42


let r2 = match just_str {
  Maybe::Just(v) => "got '{v}'",
  Maybe::Nothing => "none",
}
print(r2)  // got 'hello'


let r3 = match none {
  Maybe::Just(v) => "got {v}",
  Maybe::Nothing => "none",
}
print(r3)  // none


// Result<T, E> with two type parameters.

enum Either<L, R> {
  Left(L),
  Right(R),
}

let lf = Either.Left("error")
let rt = Either.Right(99)

print(match lf {
  Either::Left(s) => "L:{s}",
  Either::Right(n) => "R:{n}",
})

// L:error


print(match rt {
  Either::Left(s) => "L:{s}",
  Either::Right(n) => "R:{n}",
})
// R:99

Desafio

Escreva uma função genérica swap<A, B>(a: A, b: B) -> Pair<B, A> que devolve os valores na ordem trocada. Use o struct Pair do exemplo de structs genéricos.

Veja também

Buscar no Zolo

9 resultados

enespt-br