- Zig se basa en una sintaxis con llaves similar a la de Rust, pero la mejora con una semántica del lenguaje más simple y decisiones sintácticas más refinadas
- Los literales enteros comienzan todos con el tipo
comptime_int y se convierten explícitamente al asignarse, mientras que los literales de cadena usan una notación concisa de cadenas raw basada en \\
- Los literales de registro en la forma
.x = 1 hacen que la escritura de campos sea fácil de buscar, y todos los tipos se expresan de forma consistente con notación de prefijo
- Usa
and y or como palabras clave de control de flujo, y las construcciones if y loop pueden omitir llaves opcionalmente, mientras el formateador garantiza la seguridad
- Sin namespaces, todo se trata como una expresión, unificando la sintaxis de tipos, valores y patrones, y permitiendo usar de forma concisa genéricos, literales de registro y funciones integradas (
@import, @as, etc.)
Resumen general
- Zig tiene una apariencia similar a Rust, pero adopta una estructura de lenguaje más simple
- El diseño de su sintaxis se enfoca en la facilidad para buscar con grep, la consistencia sintáctica y la reducción del ruido visual innecesario
Literales enteros
const an_integer = 92;
assert(@TypeOf(an_integer) == comptime_int);
const x: i32 = 92;
const y = @as(i32, 92);
- Todos los literales enteros son de tipo
comptime_int
- Al asignarlos a una variable, hay que indicar el tipo explícitamente o convertirlos con
@as
- La forma
var x = 92; no funciona; se requiere un tipo explícito
Literales de cadena
const raw =
\\Roses are red
\\ Violets are blue,
\\Sugar is sweet
\\ And so are you.
\\
;
- Cada línea es un token independiente, así que no hay problemas de indentación
- No hace falta escapar
\\ en sí mismo
Literales de registro
const p: Point = .{
.x = 1,
.y = 2,
};
- El formato
.x = 1 ayuda a distinguir mejor entre lectura y escritura
- La notación
.{} se diferencia de un bloque y se convierte automáticamente al tipo de resultado
Notación de tipos
u32 // entero
[3]u32 // arreglo de longitud 3
?[3]u32 // arreglo anulable
*const ?[3]u32 // puntero constante
- Todos los tipos usan notación de prefijo
- La desreferenciación usa notación de sufijo (
ptr.*)
Identificadores
const @"a name with space" = 42;
- Permite evitar conflictos con palabras clave o asignar nombres especiales
Declaración de funciones
pub fn main() void {}
fn add(x: i32, y: i32) i32 {
return x + y;
}
- La palabra clave
fn y el nombre de la función van juntos, lo que facilita la búsqueda
- No usa
-> para indicar el tipo de retorno
Declaración de variables
const mid = lo + @divFloor(hi - lo, 2);
var count: u32 = 0;
- Usa
const y var
- La anotación de tipo sigue el orden
nombre: tipo
Control de flujo: and/or
while (count > 0 and ascii.isWhitespace(buffer[count - 1])) {
count -= 1;
}
and y or son palabras clave de control de flujo
- Para operaciones bit a bit se usan
&, |
Sentencia if
.direction = if (prng.boolean()) .ascending else .descending;
- Los paréntesis son obligatorios; las llaves son opcionales
zig fmt garantiza un formato seguro
Bucles
for (0..10) |i| {
print("{d}\n", .{i});
} else @panic("loop safety counter exceeded");
- Tanto
for como while admiten cláusula else
- La disposición del iterador y del nombre del elemento resulta intuitiva
Namespaces y resolución de nombres
const std = @import("std");
const ArrayList = std.ArrayList;
- No se permite el shadowing de variables
- No hay namespaces ni imports globales
Todo es una expresión
const E = enum { a, b };
const e: if (true) E else void = .a;
- Unifica la sintaxis de tipos, valores y patrones
- Se pueden usar expresiones condicionales en la posición de un tipo
Genéricos
fn ArrayListType(comptime T: type) type {
return struct {
fn init() void {}
};
}
var xs: ArrayListType(u32) = .init();
- Los genéricos se expresan con sintaxis de llamada a función (
Type(T))
- Los argumentos de tipo siempre son explícitos
Funciones integradas
const foo = @import("./foo.zig");
const num = @as(i32, 92);
- El prefijo
@ invoca funciones provistas por el compilador
@import muestra claramente la ruta del archivo
- El argumento debe ser obligatoriamente un literal de cadena
Conclusión
- La sintaxis de Zig es un caso donde un conjunto de pequeñas decisiones se junta para crear un lenguaje agradable de leer
- Al reducir la cantidad de funciones del lenguaje, también se reduce la sintaxis necesaria y disminuye la posibilidad de choques entre construcciones
- Toma prestadas las buenas ideas de lenguajes existentes, pero cuando hace falta introduce con decisión una sintaxis nueva
Aún no hay comentarios.