Pular para o conteúdo
Nesta página

Decoradores

Decoradores são anotações que modificam o comportamento de funções e structs. Eles usam a sintaxe @name colocada antes de uma declaração.

@test

Marca uma função como um teste. As funções de teste são coletadas e executadas com zolo test.

@test
fn test_addition() {
    assert_eq(2 + 2, 4, "basic math")
}

@test
fn test_string_concat() {
    let result = "hello" + " " + "world"
    assert_eq(result, "hello world", "string concat")
}

Executando Testes

zolo test my_tests.zolo              # executar todos os testes
zolo test my_tests.zolo --filter fib # apenas testes correspondentes
zolo test my_tests.zolo --list       # listar nomes dos testes

Asserções de Teste

assert_eq(actual, expected, "message")   // assert equality
assert_ne(actual, expected, "message")   // assert inequality

@memoize

Armazena em cache automaticamente os resultados das funções. Chamadas repetidas com os mesmos argumentos retornam o valor em cache em vez de recomputar.

@memoize
fn fibonacci(n: int) -> int {
    if n <= 1 { n } else { fibonacci(n - 1) + fibonacci(n - 2) }
}

// First call computes normally
print(fibonacci(40))  // fast! cached intermediate results

// Subsequent calls with same args are instant
print(fibonacci(40))  // returns from cache

Como Funciona

O compilador envolve a função com uma tabela de cache. Os argumentos são serializados como uma chave e o resultado é armazenado. Em chamadas repetidas com os mesmos argumentos, o resultado em cache é retornado imediatamente.

Melhor Uso Para

  • Funções recursivas (como fibonacci, travessias de árvore)
  • Funções puras com computação cara
  • Funções chamadas repetidamente com os mesmos argumentos

Limitações

  • Funciona apenas com argumentos serializáveis
  • O cache cresce sem limite (sem evicção)
  • Não adequado para funções com efeitos colaterais

@deprecated

Marca uma função como obsoleta. Quando chamada, imprime um aviso no stderr (uma vez por função).

@deprecated("use new_calculate() instead")
fn old_calculate(x: int) -> int {
    x * 2
}

old_calculate(5)
// stderr: WARNING: 'old_calculate' is deprecated: use new_calculate() instead

Sem Mensagem

@deprecated
fn legacy_api() {
    // ...
}

legacy_api()
// stderr: WARNING: 'legacy_api' is deprecated

Comportamento

  • O aviso é impresso apenas uma vez por função obsoleta (não em cada chamada)
  • A função ainda executa normalmente após o aviso
  • A saída vai para stderr, não para stdout

@builder

Gera um padrão builder para structs. O builder permite construir structs campo a campo com encadeamento de métodos.

@builder
struct Config {
    host: str,
    port: int,
    debug: bool,
}

let cfg = Config.builder()
    .host("localhost")
    .port(8080)
    .debug(true)
    .build()

print(cfg.host)   // "localhost"
print(cfg.port)   // 8080
print(cfg.debug)  // true

Métodos Gerados

Para cada campo name: Type na struct, @builder gera:

  • StructName.builder() — cria uma nova instância do builder
  • .field_name(value) — define o valor do campo, retorna o builder
  • .build() — cria a instância final da struct

Exemplo: Builder Complexo

@builder
struct Request {
    url: str,
    method: str,
    timeout: int,
    headers: {str: str},
}

let req = Request.builder()
    .url("https://api.example.com")
    .method("POST")
    .timeout(30)
    .build()

Decoradores Personalizados

Decoradores seguem a sintaxe:

@name
@name(arg1, arg2)

O nome e os argumentos do decorador são armazenados na AST e processados durante a compilação. Atualmente, os decoradores embutidos (@test, @memoize, @deprecated, @builder) são tratados pelo compilador. O processamento de decoradores definidos pelo usuário está planejado para uma versão futura.

Combinando Decoradores

Múltiplos decoradores podem ser aplicados a uma única declaração:

@test
@memoize
fn test_cached_fibonacci() {
    assert_eq(fibonacci(10), 55, "fib(10)")
}

Decoradores são aplicados de baixo para cima (o mais próximo da função primeiro).

Buscar no Zolo

9 resultados

enespt-br