Zig (linguagem de programação)
Zig é uma linguagem de programação de multiparadigma voltado para sistemas e compilável, embora seja de propósito geral, estaticamente tipada, projetada por Andrew Kelley.[4][5] A linguagem é projetada para "robustez, otimização e facilidade de manutenção",[6][7] suportando genéricos em tempo de compilação e reflexão, compilação cruzada e gerenciamento manual de memória.[8] Um dos principais objetivos da linguagem é competir (e melhorar) a linguagem C,[9][10] ao mesmo tempo que se inspira em Rust,[11][3] entre outros. Zig tem muitos recursos para programação de baixo nível, notavelmente como: packed struct (estrutura de variáveis O compilador é escrito em Zig, atualmente utiliza LLVM[14] como back-end[15][16] principal além de possuir um back-end próprio ainda em desenvolvimento, suportando muitos de seus alvos nativos.[17] O compilador é um software livre e de código aberto sob a licença MIT.[18] O compilador Zig expõe a capacidade de compilar C e C++, semelhante ao Clang, usando os comandos O desenvolvimento Zig é financiado pela Zig Software Foundation (ZSF), uma corporação sem fins lucrativos comandado por Andrew Kelley como presidente, que recebe doações e contrata vários empregados a tempo inteiro. FilosofiaSem estruturas de controle ocultaSe o código Zig não parece estar pulando para chamar uma função, então não está. Isso significa que você pode ter certeza de que o código a seguir chama apenas var a = b + c.d; foo (); bar (); D tem as funções Sem Alocações ocultasZig tem uma abordagem de trabalho manual quando se trata de alocação de memória. Não há uma palavra-chave Exemplo de alocações ocultas:
Quase todas as linguagens que possuem coletor de lixo têm alocações ocultas, já que o coletor de lixo esconde as evidências no lado da liberação de memória. O principal problema com alocações ocultas é que elas impedem a reusabilidade de um pedaço do código, limitando desnecessariamente o número de ambientes aos quais o código seria apropriado para ser implantado. Simplificando, existem casos de uso em que se deve ser capaz de confiar no fluxo de controle e chamadas de função para não ter o efeito colateral da alocação de memória, portanto, uma linguagem de programação só pode servir a estes casos de uso se ela puder fornecer esta garantia de forma realista. Em Zig, há recursos da biblioteca padrão que fornecem e trabalham com alocadores de memória, mas esses são recursos opcionais da biblioteca padrão, já que não são incorporados a linguagem. Se você nunca inicializar um alocador de memória, você pode ter certeza de que seu programa não irá alocar memória. Cada recurso da biblioteca padrão que precisa alocar memória aceita um parâmetro Alocadores personalizados fazem gerenciamento manual de memória com facilidade. Zig tem um alocador de depuração que mantém a segurança da memória em casos de ponteiro selvagem e liberação dupla. Ela automaticamente detecta e imprime vestígios de vazamentos de memória na pilha. Há um alocador de arena para que você possa agrupar qualquer número de alocações em uma e liberá-las todas de uma só vez, em vez de gerenciar cada alocação independentemente. Alocadores para fins especiais podem ser usados para melhorar o desempenho ou uso de memória para qualquer necessidade específica de aplicação. AutonomiaZig tem uma biblioteca padrão inteiramente opcional que só é compilada em seu programa se você a utilizar. O mesmo ocorre com a biblioteca C, a utilização dela é opcional, exceto em casos de interoperabilidade com linguagem C. O Zig é amigável ao desenvolvimento de sistemas embarcados e bare-metal. Uma linguagem portátil para bibliotecasUm dos santo graal da programação é a reutilização de código. Infelizmente, na prática, acabamos reinventando a roda várias vezes. Muitas vezes é justificado.
SimplicidadeC++, Rust e D têm um grande número de recursos e podem desviar a atenção do significado real do aplicativo em que você está trabalhando. Alguém se encontra depurando seu conhecimento da linguagem de programação em vez de depurar o próprio aplicativo. O Zig não possui macros nem metaprogramação, mas ainda assim é poderoso o suficiente para expressar programas complexos de uma forma clara e não repetitiva. Inclusive o Rust que possui casos especiais de macros Quando você olha para o código Zig, tudo é uma expressão simples ou uma chamada de função. Não há sobrecarga de operador, métodos de propriedade, despacho de tempo de execução, macros ou fluxo de controle oculto. Zig busca toda a bela simplicidade de C, exceto as armadilhas. Etapas do CompiladorRecentemente houve mudanças no bootstrap no qual é utilizado uma versão anterior do zig no formato Wasm.[21] AntesO processo de desenvolvimento do compilador se encontra em 4 etapas, embora apenas 3 sejam aderidos atualmente.
DepoisDurante essa mudança o compilador deixou de possuir mais de 80,000 linhas de código escritos em C++ e também torna o parâmetro Representação VisualAs demais etapas posteriores ao 1 (um), apresentam instabilidade com a biblioteca padrão, embora suportem mais plataformas e sistemas, quanto ao 0 (zero) serve apenas como base inicial. O objetivo é tornar-se totalmente independente do LLVM, aderindo a Etapa 2 (dois) como padrão, previsto na versão 1.0. Software desenvolvido em Zig
ExemplosOlá Mundo - Concatenação de Stringsconst std = @import("std");
const debug = std.debug;
const heap = std.heap;
const mem = std.mem;
// '!' esta sintaxe antes do tipo void indica ao compilador Zig que a função retornará um erro ou um valor.
pub fn main() !void {
const ola = "Olá,";
// Qualquer variavel const ou valor literal é de tempo de compilação
debug.print("\n{}{}\n", .{ ola, " mundo!" });
// Método 1: concatenação de arranjo (array)
// Só funciona se os valores forem de tempo de compilação.
const ola_mundo_at_comptime = ola ++ " mundo!";
debug.print("{}\n", .{ola_mundo_at_comptime});
// Método 2: std.mem.concat - Biblioteca padrão
var buf: [128]u8 = undefined;
// Alocando um tamanho fixo de memória, equivalente ao tamanho do buf
const allocator = &heap.FixedBufferAllocator.init(&buf).allocator;
const ola_mundo_concatenated = try mem.concat(allocator, u8, &[_][]const u8{ ola, " mundo!" });
debug.print("{}\n", .{ola_mundo_concatenated});
// Método 3: std.mem.join - Biblioteca padrão
const ola_mundo_joined = try mem.join(allocator, " ", &[_][]const u8{ ola, "mundo!" });
debug.print("{}\n", .{ola_mundo_joined});
}
Interoperabilidade com Cconst std = @import("std").c;
const c = @cImport({
// Veja em: https://github.com/ziglang/zig/issues/515
// @cDefine("_NO_CRT_STDIO_INLINE", "1");
@cInclude("stdio.h");
});
pub fn main() void {
_ = std.printf("Método 1: Código C em Zig!\n"); // Requer libc (nativo do sistema)
_ = c.printf("Método 2: Código C em Zig!\n"); // Requer libc (nativo do sistema)
}
// Compilação: zig build-exe ffi.zig -lc
Fibonacciconst expect = @import("std").testing.expect;
fn fibonacci(index: u32) u32 {
if (index < 2) return index;
return fibonacci(index - 1) + fibonacci(index - 2);
}
test "fibonacci" {
// testando a função de fibonacci em tempo de execução
expect(fibonacci(7) == 13);
// testando a função de fibonacci em tempo de compilação
comptime {
expect(fibonacci(7) == 13);
}
}
// Saída:
// $ zig test test.zig
// 1/1 test "fibonacci"... OK
// All 1 tests passed.
Lista encadeada genéricafn LinkedList(comptime T: type) type {
return struct {
pub const Node = struct {
prev: ?*Node,
next: ?*Node,
data: T,
};
first: ?*Node,
last: ?*Node,
len: usize,
};
}
pub fn main() void {
var node = LinkedList(i32).Node {
.prev = null,
.next = null,
.data = 1234,
};
var list = LinkedList(i32) {
.first = &node,
.last = &node,
.len = 1,
};
}
Ver tambémReferências
Ligações externas |