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 testesAsserçõ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 cacheComo 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() insteadSem Mensagem¶
@deprecated
fn legacy_api() {
// ...
}
legacy_api()
// stderr: WARNING: 'legacy_api' is deprecatedComportamento¶
- 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) // trueMé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).