Articulo de referencia

Zig (lenguaje de programación)

{{cite web |last=Kelley |first=Andrew |title=Introduction to the Zig Programming Language |url=https://andrewkelley.me/post/intro-to-zig.html |website=andrewkelley.me |date=2016...

Zig es un lenguaje de programación de sistemas diseñado para ser una mejora de propósito general del lenguaje de programación C. [ 11 ] Es software libre y de código abierto , publicado bajo una licencia MIT en Codeberg , una plataforma para compartir código fuente . [ 12 ]

Las diferencias con C se relacionan con el flujo de control , las llamadas a funciones , las importaciones de bibliotecas , la declaración de variables y la compatibilidad con Unicode . El lenguaje no utiliza macros ni instrucciones de preprocesador . Las características adoptadas de lenguajes modernos incluyen la adición de tipos de datos de programación genéricos en tiempo de compilación , lo que permite que las funciones trabajen con una variedad de datos, junto con un pequeño conjunto de nuevas directivas del compilador para permitir el acceso a la información sobre esos tipos mediante reflexión . [ 13 ] Zig requiere gestión manual de la memoria . [ 13 ] Las características para la programación de bajo nivel incluyen estructuras empaquetadas, enteros de ancho arbitrario [ 14 ] y múltiples tipos de punteros . [ 15 ]

Zig fue diseñado por Andrew Kelley y anunciado por primera vez en 2016. [ 1 ] El desarrollo es financiado por la Fundación de Software Zig (ZSF), que recibe patrocinios corporativos y donaciones personales. [ 16 ] [ 17 ]

Idioma

Objetivos

El objetivo principal de Zig es ofrecer una mejor solución para las tareas que actualmente se resuelven con C. Una preocupación fundamental en este sentido es la legibilidad; Zig intenta utilizar conceptos y sintaxis existentes siempre que sea posible, evitando añadir sintaxis diferentes para conceptos similares. Además, su objetivo es ser un lenguaje diseñado para la robustez, la optimización y la mantenibilidad. La sintaxis pequeña y sencilla es una parte importante de esa mantenibilidad, ya que uno de los objetivos del lenguaje es permitir a los mantenedores depurar código escrito en Zig sin tener que aprender las complejidades de un lenguaje con el que quizás no estén familiarizados. [ 18 ] Incluso con estos cambios, Zig puede compilarse en y contra código C existente; los encabezados de C pueden incluirse en un proyecto Zig y sus funciones pueden llamarse, y el código Zig puede vincularse a proyectos C incluyendo los encabezados generados por el compilador. [ 19 ]

El manejo de errores se realiza mediante tipos de error y se puede manejar con catcho try. Los genéricos se logran mediante la generación de código en tiempo de compilación y la adaptación a una forma de tipado dinámico con la comptimedirectiva.

Manejo de memoria

La asignación de memoria en la biblioteca estándar de Zig sigue la convención de que la asignación se maneja a través de structinstrucciones que describen la acción, en lugar de llamar a las funciones de administración de memoria en libc . Por ejemplo, en C, si se quiere escribir una función que cree una cadena que contenga múltiples copias de otra cadena, la función podría tener este aspecto:

const char * repeat ( const char * original , size_t times );

En el código, la función examinaría el tamaño originaly luego timesasignaría memoria con `malloc` para reservar esa longitud para la cadena que construirá. Esta asignación es invisible para las funciones que la llaman; si no liberan la memoria posteriormente, se producirá una fuga de memoria. En Zig, esto podría manejarse usando una función como:

const Asignador = std.mem.Asignador ;fn repeat ( allocator : Allocator , original : [] const u8 , times : usize ) Allocator . Error ! [] const u8 ;

En este código, a la allocatorvariable se le pasa una estructura que describe qué código debe realizar la asignación, y la repeatfunción devuelve la cadena resultante o, utilizando el tipo opcional indicado por !, un Allocator.Error. Al expresar directamente el asignador como entrada, la asignación de memoria nunca se "oculta" dentro de otra función, sino que siempre se expone a la API mediante la función que finalmente solicita la memoria que se va a asignar. No se realizan asignaciones dentro de la biblioteca estándar de Zig . Además, como la estructura puede apuntar a cualquier cosa, se pueden usar asignadores alternativos, incluso los escritos en el programa. Esto puede permitir, por ejemplo, asignadores de objetos pequeños que no utilizan las funciones del sistema operativo que normalmente asignan una página de memoria completa . [ 20 ]

Los tipos opcionales son un ejemplo de una característica del lenguaje que ofrece funcionalidad general sin dejar de ser simple y genérica. No es necesario usarlos para resolver problemas de punteros nulos; también son útiles para cualquier tipo de valor donde "ningún valor" sea una respuesta apropiada. Consideremos una función countTheNumberOfUsersque devuelve un entero y una variable entera theCountedUsersque almacena el resultado. En muchos lenguajes, se colocaría un número mágicotheCountedUsers para indicar que countTheNumberOfUsersaún no se ha llamado a la función, mientras que muchas implementaciones simplemente lo establecerían a cero. En Zig, esto podría implementarse como un valor que establece la variable a un valor claro de "no se ha llamado". [ 20 ]vartheCountedUsers:?i32=null

Otra característica más general de Zig que también ayuda a gestionar los problemas de memoria es el concepto de defer, que marca cierto código para que se ejecute al final de un ámbito pase lo que pase, incluidos los posibles errores de tiempo de ejecución. Si una función en particular asigna memoria y luego la libera cuando la operación se completa, se puede agregar una línea para diferir un freey asegurar que se libere pase lo que pase. [ 20 ]

La biblioteca estándar de Zig evita las asignaciones ocultas. La asignación no se gestiona directamente en el lenguaje. En cambio, el acceso al montón se realiza a través de la biblioteca estándar , explícitamente. [ 21 ]

Interacción directa con C

Zig promueve un enfoque gradual hacia la portabilidad que combina el nuevo código Zig con el código C existente. Para ello, busca que la interacción con las bibliotecas C existentes sea lo más fluida posible. Zig importa sus propias bibliotecas con la @importdirectiva, generalmente de esta manera:

const std = @import ( "std" );

El código Zig dentro de ese archivo ahora puede llamar a funciones dentro de std, por ejemplo:

std.debug.print ( " ¡ Hola, mundo! \ n " , . { });

Para trabajar con código C, simplemente se reemplaza @importpor @cImport:

const c = @cImport ( @cInclude ( "soundio/soundio.h" ));

El código Zig ahora puede llamar a funciones de la biblioteca soundio como si fueran código Zig nativo. Como Zig utiliza nuevos tipos de datos que se definen explícitamente, a diferencia de los más genéricos de C int, floatse utiliza un pequeño número de directivas para transferir datos entre los tipos de C y Zig, incluidas @intCasty @ptrCast. [ 20 ]

Zig 0.16.0 está obsoleto @cImport; en adelante, la traducción a C se gestionará a través del sistema de compilación en lugar de utilizar la @cImportfunción integrada del lenguaje, que ha sido eliminada. Además, esta versión está obsoleta std.Build.Step.TranslateC y se recomienda utilizar una dependencia explícita del paquete oficial translate-c, que es la misma implementación que la versión anterior del paso de compilación con opciones de configuración adicionales. [ 22 ]

Como resultado, el ejemplo utilizado anteriormente para la inclusión de código C, tal como lo usaban las versiones de Zig antes del cambio, requiere migración; cualquier archivo de encabezado C tendría que importarse usando el sistema de compilación. Para migrar el ejemplo anterior, por ejemplo, se requiere la creación de un archivo de encabezado simple con líneas de inclusión C estándar añadidas: [ 23 ]

#include <soundio/soundio.h>

Este archivo de encabezado debe referenciarse de la siguiente manera dentro del build.zigarchivo utilizado por el proyecto (en este ejemplo, el archivo se ha nombrado c.hen el srcdirectorio): [ 22 ]

const Translator = @import ( "translate_c" ). Translator ;const translate_c = b . dependency ( "translate_c" , .{});const traductor : Traductor = .init ( translate_c , .{ .c_source_file = b .path ( " src /ch" ) , .target = target , .optimize = optimize , } ) ; traductor .linkSystemLibrary ( "soundio" , . { });const exe = b . addExecutable (.{ . name = "hello-sound" , . root_module = b . createModule (.{ . root_source_file = b . path ( "src/main.zig" ), . optimize = optimize , . target = target , . imports = & .{ .{ . name = "c" , . module = translator . mod , }, }, }), });

Tras el cambio para llamar a las funciones de la biblioteca soundio, se requeriría lo siguiente en el código nativo de Zig:

const c = @import ( "c" );

Tiempo de compensación

Al usar la comptimepalabra clave, el programador puede hacer que Zig evalúe explícitamente secciones de código en tiempo de compilación , en lugar de en tiempo de ejecución . Poder ejecutar código en tiempo de compilación permite que Zig tenga la funcionalidad de macros y compilación condicional sin necesidad de un lenguaje de preprocesador independiente . [ 24 ]

Durante el tiempo de compilación, los tipos se convierten en ciudadanos de primera clase . Esto permite el tipado dinámico en tiempo de compilación y es como Zig implementa los tipos genéricos. [ 15 ]

Por ejemplo, en Zig, un tipo genérico de lista enlazada podría implementarse utilizando una función como:

fn ListaEnlazada ( comptime T : tipo ) tipo ;

Esta función recibe un tipo de dato Ty devuelve structuna lista enlazada personalizada que define ese tipo de dato.

Compilador

Zig también incluye un compilador de C y C++, y puede usarse con uno o ambos lenguajes aprovechando los comandos zig ccy zig c++, [ 25 ] proporcionando muchos encabezados, incluyendo la biblioteca estándar de C (libc) y la biblioteca estándar de C++ (libcxx) para muchas plataformas diferentes. Esto permite que los subcomandos de Zig actúen como cccompiladores cruzados de forma predeterminada (de manera similar a Clang ). [ 26 ] [ 27 ]c++

Zig trata la compilación cruzada como un caso de uso de primera clase del lenguaje. [ 13 ] Esto significa que cualquier compilador Zig puede compilar binarios ejecutables para cualquiera de sus plataformas de destino, de las cuales hay docenas. Estas incluyen no solo sistemas modernos ampliamente utilizados como ARM y x86-64 , sino también PowerPC , SPARC , MIPS , RISC-V , LoongArch64 e incluso las arquitecturas IBM z/ (S390). La cadena de herramientas puede compilar para cualquiera de estos destinos sin instalar software adicional, todo el soporte necesario está en el sistema básico. [ 20 ] También se proporciona soporte experimental para plataformas menos conocidas como las GPU AMD y Nvidia o PlayStation 4 y 5 (con diversos grados de soporte).

También está disponible la compilación cruzada para diversos sistemas operativos (principalmente de escritorio). Los sistemas populares tipo UNIX y Windows cuentan con soporte oficial (y documentación), pero se pueden crear aplicaciones (mínimas) para Android (con Android NDK ) o iOS .

Zig utiliza LLVM (escrito en C++) como motor de optimización. Desde la versión 0.10, el compilador de Zig está escrito en el lenguaje de programación Zig; es decir, es un compilador autoalojado . El enlazador autoalojado está estrechamente integrado con el compilador autoalojado.

El backend LLVM es el predeterminado para la mayoría de los destinos, excepto para SPIR-V y x86-64 [ 28 ] (aunque actualmente solo está en modo Debug). Zig también admite su backend autohospedado que se puede habilitar usando -fno-llvm.

Historia

Kelley comenzó a desarrollar una estación de trabajo de audio digital , [ 29 ] pero encontró que la interoperabilidad de Go con las bibliotecas de C era difícil y descubrió que el recolector de basura causaba retrasos en el audio. Probó con C++, pero descubrió que pequeños errores provocaban errores de corrupción de memoria que tardaban semanas en solucionarse. Probó con Rust, pero "realmente tuvo dificultades para escribir código que cumpliera con las reglas de Rust" y pasó un mes intentando que funcionara la representación de fuentes. [ 30 ]

El nombre Zig fue elegido usando un script que generaba combinaciones aleatorias de letras que comenzaban con la letra z . [ 31 ]

El compilador de arranque anterior , escrito en Zig y C++ usando LLVM como back-end, [ 32 ] [ 33 ] que admitía muchos de sus objetivos nativos, [ 34 ] fue eliminado en la versión 0.11. Las versiones más recientes de Zig usan una versión precompilada de WebAssembly de Zig para arrancarse a sí misma.

El 26 de noviembre de 2025, el desarrollo de Zig migró de GitHub a Codeberg , citando la disminución de la fiabilidad de GitHub como razón principal. [ 35 ]

Paquetes

La versión 0.11.0 incluye un gestor de paquetes experimental , pero no dispone de un repositorio oficial. En su lugar, un paquete es simplemente una URL que apunta a un archivo comprimido o a un repositorio Git . Idealmente, cada paquete incluye un archivo estándar (que el compilador Zig utiliza por convención para compilar el código fuente) y un archivo con metadatos que incluye el nombre y la versión del paquete.build.zigbuild.zig.zon

Ejemplos

Hola Mundo

const std = @import ( "std" ); const File = std . Io . File ;pub fn main ( init : std . process . Init ) ! void { _ = try File . stdout (). writeStreamingAll ( init . io , "Hello, World! \n " ); }

Lista enlazada genérica

const std = @import ( "std" ); const FormatOptions = std . fmt . FormatOptions ; const stdout = std . io . getStdOut (). writer ();fn LinkedList ( comptime T : type ) type { return struct { const Self = @This ();pub const Nodo = struct { siguiente : ?* Nodo = null , datos : T , };primero : ?* Nodo = null ,pub fn prepend ( lista : * Self , nuevo_nodo : * Nodo , ) void { nuevo_nodo . siguiente = lista . primero ; lista . primero = nuevo_nodo ; }pub fn format ( list : Self , comptime fmt : [] const u8 , options : FormatOptions , out_stream : anytype , ) ! void { try out_stream . writeAll ( "( " );var it = list . first ; while ( it ) | node | : ( it = node . next ) { try std . fmt . formatType ( node . data , fmt , options , out_stream , 1 , );prueba out_stream.writeAll ( " " ) ; }prueba out_stream.writeAll ( " )" ); } } ; }pub fn main () ! void { const ListU32 = LinkedList ( u32 );lista var = ListaU32 {}; var nodo1 = ListaU32 . Nodo { . datos = 1 }; var nodo2 = ListaU32 . Nodo { . datos = 2 }; var nodo3 = ListaU32 . Nodo { . datos = 3 };lista.anteponer ( & nodo1 ) ; lista.anteponer ( & nodo2 ) ; lista.anteponer ( & nodo3 ) ;try stdout . print ( "{} \n " , .{ list }); try stdout . print ( "{b} \n " , .{ list }); }

Producción:

( 3 2 1 ) ( 11 10 1 )

Repetición de cadena con asignador

const std = @import ( "std" ); const ArenaAllocator = std . heap . ArenaAllocator ; const Allocator = std . mem . Allocator ;fn repeat ( allocator : Allocator , original : [] const u8 , times : usize , ) Allocator . Error ! [] u8 { const buffer = try allocator . alloc ( u8 , original . len * times , );para ( 0 .. veces ) | i | { std . mem . copyForwards ( u8 , buffer [( original . len * i )..], original , ); }devolver buffer ; }pub fn main () ! void { var arena = ArenaAllocator . init ( std . heap . page_allocator , ); defer arena . deinit ();const asignador = arena.allocator ( ) ;const original = "Hola " ; const repetido = intentar repetir ( asignador , original , 3 , );std.debug.print ( " { s} \ n " , .{ repetido } ) ; }

Producción:

Hola Hola Hola

Proyectos destacados

Entre los proyectos que utilizan (o han utilizado anteriormente) Zig se incluyen:

Referencias

Citas

  1. 1 2 Kelley, Andrew (8 de febrero de 2016). "Introducción al lenguaje de programación Zig" . andrewkelley.me . Recuperado el 8 de noviembre de 2020 .
  2. "0.16.0 Publicado" . 14 de abril de 2026. Consultado el 14 de abril de 2026 .
  3. "¿Cuáles son las ventajas y desventajas de Zig frente a Rust? Veo que Zig se menciona cada vez más aquí... | Hacker News" .
  4. "¿Por qué Zig cuando ya existen C++, D y Rust? ⚡ Lenguaje de programación Zig" .
  5. "Sin sorpresas en ningún sistema: Preguntas y respuestas con Loris Cro de Zig - Stack Overflow" . 2 de octubre de 2023.
  6. "La nueva relación de Zig con LLVM | Hacker News" .
  7. "¿Qué tiene Zig que no tengan C, Rust y Go? (Con Loris Cro)" . YouTube . 15 de noviembre de 2023.
  8. "¿Por qué Zig cuando ya existen C++, D y Rust? | Hacker News" .
  9. "Introducción ⚡ Lenguaje de programación Zig" .
  10. "Después de un día de programación en Zig" . 29 de diciembre de 2023. Archivado del original el 11 de febrero de 2025. Consultado el 31 de diciembre de 2024 .
  11. "Desvelando los defectos de C, con Andrew Kelley, creador del lenguaje de programación Zig" . Sourcegraph . 19 de octubre de 2021. Archivado del original el 5 de enero de 2025. Consultado el 18 de abril de 2024 .
  12. "ziglang/zig" . Codeberg . Consultado el 11 de febrero de 2020 .
  13. 1 2 3 "El lenguaje de programación Zig" . Ziglang.org . Consultado el 11 de febrero de 2020 .
  14. Anderson, Tim (24 de abril de 2020). "¿Con ganas de usar _ExtInt? El compilador LLVM Clang añade soporte para enteros de ancho personalizado" . www.theregister.co.uk . Consultado el 30 de diciembre de 2024 .
  15. 1 2 "Documentación" . Ziglang.org . Consultado el 24 de abril de 2020 .
  16. "Anuncio de la Fundación de Software Zig" . Ziglang.org . Consultado el 28 de mayo de 2021 .
  17. "Prometiendo otros 400.000 dólares a la Fundación Zig Software" . Mitchell Hashimoto . 21 de junio de 2026. Consultado el 7 de julio de 2026 .
  18. Elizabeth 2017 .
  19. Yegulalp 2016 .
  20. 1 2 3 4 5 "Asignadores" . 11 de septiembre de 2023.
  21. Tyson, Matthew (9 de marzo de 2023). "Conoce a Zig: La alternativa moderna a C" . InfoWorld.com .
  22. 1 2 "Notas de la versión Zig 0.16.0" . Notas de la versión Zig . 14 de abril de 2026. Consultado el 24 de abril de 2026 .{{cite web}}: CS1 mantenimiento: estado de la URL ( enlace )
  23. "Notas de la versión 0.16.0: @cImport se traslada al sistema de compilación" . ziglang.org . Consultado el 17 de julio de 2026 .
  24. El camino hacia Zig 1.0 - Andrew Kelley . ChariotSolutions. 9 de mayo de 2019 vía YouTube .
  25. "Notas de la versión 0.6.0" . Ziglang.org . Consultado el 19 de abril de 2020 .
  26. "'zig cc': un potente reemplazo directo para GCC/Clang - Andrew Kelley" . andrewkelley.me . Consultado el 28 de mayo de 2021 .
  27. "Zig hace que la compilación cruzada de Go simplemente funcione" . Comunidad DEV . 24 de enero de 2021. Consultado el 28 de mayo de 2021 .
  28. "Notas de la versión 0.15.1 ⚡ El lenguaje de programación Zig" . ziglang.org . Consultado el 3 de septiembre de 2025 .
  29. andrewrk. "daw" . Codeberg.org . Consultado el 29 de mayo de 2026 .
  30. Anderson, Tim (28 de mayo de 2026). "El creador de Zig busca la 'perfección sin concesiones' antes de dar la bendición a la versión 1.0" . theregister . Consultado el 29 de mayo de 2026 .
  31. andrewrk (13 de marzo de 2024). "Origen del nombre del lenguaje de programación Zig. Por @andrewrk" . Consultado el 13 de marzo de 2024 .
  32. "Una respuesta a _El camino a Zig 1.0_" . www.gingerbill.org . 13 de mayo de 2019. Consultado el 11 de febrero de 2020 .
  33. "ziglang/zig" . Codeberg . Lenguaje de programación Zig. 11 de febrero de 2020. Consultado el 11 de febrero de 2020 .
  34. "El lenguaje de programación Zig" . Ziglang.org . Consultado el 11 de febrero de 2020 .
  35. Kelley, Andrew (26 de noviembre de 2025). "Migrando de GitHub a Codeberg" . ziglang.org . Archivado del original el 27 de noviembre de 2025. Recuperado el 27 de noviembre de 2025 .
  36. Sumner, Jarred (8 de julio de 2026). "Reescribiendo Bun en Rust" . Blog de Bun .
  37. Greef, Joran Dirk (4 de agosto de 2023). "Una nueva era para el diseño de bases de datos con TigerBeetle" . InfoQ . Consultado el 28 de enero de 2026 .
  38. escarabajo tigre/escarabajo tigre , Escarabajo Tigre, 28 de enero de 2026 , consultado el 28 de enero de 2026
  39. Proven, Liam (8 de enero de 2025). "Justo cuando pensabas que los emuladores de terminal no podían ser mejores, Ghostty llega" . The Register .

Bibliografía

  • Elizabeth, Jane (19 de octubre de 2017). "¿Cansado de C? El nuevo lenguaje de programación Zig pretende ser más pragmático y legible" . jaxenter . Archivado del original el 1 de octubre de 2020. Consultado el 22 de abril de 2020 .
  • Yegulalp, Serdar (29 de agosto de 2016). "Un nuevo competidor se une a Rust para derrocar al lenguaje C" . InfoWorld . Recuperado el 11 de febrero de 2020 .