---
title: "Writer Interface em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/writer-interface-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/writer-interface-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda a Writer interface em Zig: padrão para escrita genérica em arquivos, buffers, sockets e qualquer destino de dados. Guia pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Writer Interface em Zig — O que é e Como Usar

Entenda a Writer interface em Zig: padrão para escrita genérica em arquivos, buffers, sockets e qualquer destino de dados. Guia pt-BR.


# Writer Interface em Zig — O que é e Como Usar

## Definição

A **Writer interface** em Zig é o padrão utilizado pela biblioteca padrão para abstração de escrita de dados. Qualquer tipo que forneça uma função `write` com a assinatura correta pode ser usado como Writer. Isso permite escrever código genérico que funciona com stdout, arquivos, buffers em memória, sockets de rede ou qualquer outro destino de dados.

Em Zig, interfaces são implementadas via `anytype` (duck typing em comptime) ou via o tipo concreto `std.io.Writer`, que usa uma vtable para dispatch dinâmico.

## Por que Writer Interface Importa

1. **Código genérico**: Uma função que aceita `anytype` writer funciona com qualquer destino.
2. **Testabilidade**: Escrever em buffer para testes, em arquivo para produção.
3. **Composição**: Writers podem ser encadeados (buffered writer, counting writer, etc.).
4. **Padrão da std lib**: Formatação, logging e serialização usam a Writer interface.

## Exemplo Prático

### Função Genérica com Writer

```zig
const std = @import("std");

fn escreverRelatorio(writer: anytype, nome: []const u8, pontos: u32) !void {
    try writer.print("Relatório de: {s}\n", .{nome});
    try writer.print("Pontuação: {}\n", .{pontos});
    try writer.print("Status: {s}\n", .{
        if (pontos >= 70) "Aprovado" else "Reprovado",
    });
    try writer.writeAll("---\n");
}

pub fn main() !void {
    // Escrever para stdout
    const stdout = std.io.getStdOut().writer();
    try escreverRelatorio(stdout, "Ana", 85);
    try escreverRelatorio(stdout, "Bruno", 60);
}
```

### Escrever em Buffer (para Testes)

```zig
const std = @import("std");

fn formatarSaudacao(writer: anytype, nome: []const u8) !void {
    try writer.print("Olá, {s}!", .{nome});
}

test "formatar saudação" {
    var buffer: [256]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buffer);
    const writer = stream.writer();

    try formatarSaudacao(writer, "Zig Brasil");

    const resultado = stream.getWritten();
    try std.testing.expectEqualStrings("Olá, Zig Brasil!", resultado);
}
```

### Buffered Writer para Performance

```zig
const std = @import("std");

pub fn main() !void {
    const arquivo = try std.fs.cwd().createFile("saida.txt", .{});
    defer arquivo.close();

    // Buffered writer reduz syscalls de escrita
    var buf_writer = std.io.bufferedWriter(arquivo.writer());
    const writer = buf_writer.writer();

    for (0..1000) |i| {
        try writer.print("Linha {}\n", .{i});
    }

    // Flush final para garantir que tudo foi escrito
    try buf_writer.flush();
}
```

## Writers Comuns na std lib

| Writer | Descrição |
|--------|-----------|
| `std.io.getStdOut().writer()` | Saída padrão (stdout) |
| `std.io.getStdErr().writer()` | Saída de erro (stderr) |
| `file.writer()` | Escrita em arquivo |
| `stream.writer()` | Escrita em fixedBufferStream |
| `std.io.bufferedWriter(w)` | Writer com buffer |
| `std.io.countingWriter(w)` | Writer que conta bytes escritos |

## Implementando um Writer Customizado

É possível criar seu próprio writer para destinos especiais — por exemplo, um writer que conta bytes, escreve com prefixo de timestamp ou envia dados por uma fila:

```zig
const std = @import("std");

// Writer que converte texto para maiúsculas
const MaiusculasContext = struct {
    inner: std.fs.File.Writer,
};

fn writeMaiusculas(ctx: *MaiusculasContext, bytes: []const u8) !usize {
    var buf: [512]u8 = undefined;
    const limite = @min(bytes.len, buf.len);
    for (bytes[0..limite], 0..) |c, i| {
        buf[i] = std.ascii.toUpper(c);
    }
    return ctx.inner.write(buf[0..limite]);
}
```

Para casos mais simples, `countingWriter` da std já oferece uma funcionalidade pronta: envolve qualquer writer e expõe `bytes_written` com o total escrito até o momento.

## Comparação com Outras Linguagens

| Linguagem | Abstração de escrita | Tipagem |
|-----------|---------------------|---------|
| Zig | `anytype` ou `std.io.Writer` (vtable) | Estática (comptime) ou dinâmica |
| Rust | `trait std::io::Write` | Estática (generics) ou `dyn Write` |
| Go | `interface io.Writer` | Dinâmica (interface) |
| C | `FILE*` ou `int fd` | Manual, sem abstração |

O Zig oferece o melhor dos dois mundos: dispatch em comptime (zero overhead) com `anytype`, e dispatch dinâmico (armazenável em structs) com `std.io.Writer`.

## Boas Práticas

- **Prefira `anytype` em funções livres**: Para funções que apenas escrevem e não armazenam o writer, `anytype` tem custo zero e aceita qualquer writer sem boxing.
- **Use `std.io.Writer` em structs**: Quando precisar guardar um writer como campo de struct, use o tipo concreto `std.io.Writer` para despacho dinâmico via vtable.
- **Sempre faça `flush` explícito**: Mesmo que seu código "funcione" sem flush, buffers não esvaziados podem perder dados em caso de crash. Combine `defer buf_writer.flush()` com tratamento de erro.
- **Trate erros de I/O**: Escrita pode falhar por disco cheio, socket encerrado, ou limite de processo. Propague sempre com `try`.

## Armadilhas Comuns

- **Flush**: Buffered writers exigem `flush()` no final para garantir que dados pendentes sejam escritos.
- **Erros de escrita**: Sempre trate os erros com `try`. Escrever pode falhar (disco cheio, socket fechado).
- **anytype vs Writer concreto**: Use `anytype` para funções simples. Use `std.io.Writer` quando precisar armazenar o writer em uma struct.
- **Performance**: Sem buffer, cada `print` pode gerar uma syscall. Use `bufferedWriter` para escrita intensiva.

## Termos Relacionados

- [Reader Interface](/glossario/reader-interface/) — Interface de leitura complementar
- [anytype](/glossario/anytype/) — Mecanismo de genéricos usado pela interface
- [Vtable Interface](/glossario/vtable-interface/) — Dispatch dinâmico para armazenar writers
- [Error Union](/glossario/error-union/) — Writers retornam `!void` ou `!usize`

## Tutoriais Relacionados

- [I/O em Zig](/tutoriais/io-em-zig/)
- [Zig Design Patterns](/tutoriais/zig-design-patterns/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
