Zig 是一门现代化的系统级编程语言,由 Andrew Kelley 创建。它的设计理念强调显式优于隐式 、编译时代码执行 、零成本抽象 以及与 C 语言的完美互操作性。本文将全面介绍 Zig 的基础语法。
变量与常量 变量声明 Zig 使用 var 声明可变变量,使用 const 声明常量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const std = @import ( "std" ) ; pub fn main ( ) void { var x: i32 = 10 ; x = 20 ; const y: i32 = 30 ; var z = 50 ; }
基本数据类型 Zig 提供了丰富的整数和浮点类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const a: i8 = - 128 ; const b: i16 = 1000 ; const c: i32 = 100000 ; const d: i64 = 1000000 ; const e: u8 = 255 ; const f: u32 = 4000000000 ; const g: f32 = 3.14 ; const h: f64 = 3.14159265359 ; const flag: bool = true ; const ch: u21 = '中' ;
未定义值 Zig 要求显式处理未初始化的变量:
1 2 var x: i32 = undefined ; x = 10 ;
数组与切片 数组 数组是固定大小的同类型元素集合:
1 2 3 4 5 6 7 8 9 10 11 const arr = [ 5 ] i32 { 1 , 2 , 3 , 4 , 5 } ; const arr2 = [ _] i32 { 1 , 2 , 3 } ; const zeros = [ _] i32 { 0 } ** 10 ; const len = arr. len;
切片 切片是对数组的引用,包含指针和长度:
1 2 3 4 5 6 7 8 9 10 var arr = [ _] i32 { 1 , 2 , 3 , 4 , 5 } ; const slice = arr[ 1 . . 4 ] ; slice[ 0 ] = 100 ; const str: [ ] const u8 = "Hello, Zig!" ;
多维数组 1 2 3 4 5 6 const matrix = [ 3 ] [ 3 ] i32 { [ _] i32 { 1 , 2 , 3 } , [ _] i32 { 4 , 5 , 6 } , [ _] i32 { 7 , 8 , 9 } , } ;
控制流 条件语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const x: i32 = 10 ; if ( x > 5 ) { std. debug. print( "x is greater than 5\n" , . { } ) ; } else if ( x == 5 ) { std. debug. print( "x equals 5\n" , . { } ) ; } else { std. debug. print( "x is less than 5\n" , . { } ) ; } const y = if ( x > 5 ) 100 else 0 ; const maybe_value: ? i32 = 42 ; if ( maybe_value) | value| { std. debug. print( "Value: {}\n" , . { value} ) ; } else { std. debug. print( "No value\n" , . { } ) ; }
循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 var i: i32 = 0 ; while ( i < 5 ) : ( i + = 1 ) { std. debug. print( "{} " , . { i} ) ; } var j: i32 = 0 ; while ( j < 10 ) : ( j + = 2 ) { if ( j == 4 ) continue ; std. debug. print( "{} " , . { j} ) ; } const arr = [ _] i32 { 1 , 2 , 3 , 4 , 5 } ; for ( arr) | elem| { std. debug. print( "{} " , . { elem} ) ; } for ( arr, 0 . . ) | elem, idx| { std. debug. print( "[{}] = {}\n" , . { idx, elem } ) ; } outer: for ( 0 . . 3 ) | a| { for ( 0 . . 3 ) | b| { if ( a + b == 3 ) break : outer; } }
switch 语句 Zig 的 switch 是详尽的(exhaustive):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const number = 5 ; const result = switch ( number) { 1 = > "one" , 2 = > "two" , 3 = > "three" , 4 . . . 10 = > "between 4 and 10" , else = > "other" , } ; const Color = enum { red, green, blue } ; const color = Color. red; const color_name = switch ( color) { . red = > "Red" , . green = > "Green" , . blue = > "Blue" , } ;
函数 函数定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 fn add ( a: i32 , b: i32 ) i32 { return a + b; } fn printHello ( ) void { std. debug. print( "Hello!\n" , . { } ) ; } fn divide ( dividend: i32 , divisor: i32 ) struct { quotient: i32 , remainder: i32 } { return . { . quotient = @divTrunc ( dividend, divisor) , . remainder = @rem ( dividend, divisor) , } ; }
递归函数 1 2 3 4 fn factorial ( n: u32 ) u32 { if ( n <= 1 ) return 1 ; return n * factorial( n - 1 ) ; }
函数指针 1 2 3 4 5 6 7 8 9 10 11 12 const MathOp = fn ( a: i32 , b: i32 ) i32 ; fn calculate ( a: i32 , b: i32 , op: MathOp) i32 { return op( a, b) ; } fn multiply ( x: i32 , y: i32 ) i32 { return x * y; } const result = calculate( 5 , 3 , multiply) ;
结构体 基本结构体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const Point = struct { x: f32 , y: f32 , pub fn distance ( self: Point, other: Point) f32 { const dx = self. x - other. x; const dy = self. y - other. y; return std. math. sqrt( dx * dx + dy * dy) ; } } ; const p1 = Point{ . x = 0 , . y = 0 } ; const p2 = Point{ . x = 3 , . y = 4 } ; const dist = p1. distance( p2) ;
默认字段值 1 2 3 4 5 6 7 8 const Config = struct { host: [ ] const u8 = "localhost" , port: u16 = 8080 , debug: bool = false , } ; const default_config = Config{ } ; const custom_config = Config{ . port = 3000 } ;
自引用结构体 1 2 3 4 const Node = struct { value: i32 , next: ? * Node = null , } ;
联合体与枚举 枚举 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const Status = enum { pending, running, completed, failed, pub fn isDone ( self: Status) bool { return self == . completed or self == . failed; } } ; const Message = union( enum ) { text: [ ] const u8 , number: i32 , quit: void , } ;
联合体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const Value = union { int: i32 , float: f64 , boolean: bool , } ; var v = Value{ . int = 42 } ; const TaggedValue = union( enum ) { int: i32 , float: f64 , boolean: bool , } ;
错误处理 Zig 使用错误联合类型(Error Union Types)进行错误处理:
定义错误 1 2 3 4 5 const FileError = error { NotFound, PermissionDenied, OutOfMemory, } ;
错误联合类型 1 2 3 4 5 6 7 8 9 10 11 12 13 fn mightFail ( condition: bool ) FileError! i32 { if ( ! condition) { return FileError. NotFound; } return 42 ; } const result = mightFail( true ) catch | err| { std. debug. print( "Error: {}\n" , . { err} ) ; return ; } ;
try 和 catch 1 2 3 4 5 6 7 8 9 10 11 const value = try mightFail( true ) ; const value_or_default = mightFail( false ) catch 0 ; const value2 = mightFail( false ) catch | err| blk: { std. debug. print( "Got error: {}\n" , . { err} ) ; break : blk - 1 ; } ;
if-else 处理错误 1 2 3 4 5 if ( mightFail( true ) ) | value| { std. debug. print( "Success: {}\n" , . { value} ) ; } else | err| { std. debug. print( "Failed: {}\n" , . { err} ) ; }
可选类型(Optionals) Zig 使用 ?T 表示类型 T 的可选值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const maybe_number: ? i32 = 42 ; const no_number: ? i32 = null ; if ( maybe_number) | n| { std. debug. print( "Number: {}\n" , . { n} ) ; } var iter = RangeIterator{ . current = 0 , . end = 5 } ; while ( iter. next( ) ) | value| { std. debug. print( "{} " , . { value} ) ; } const value = maybe_number orelse 0 ; const definite = maybe_number. ? ;
编译时计算(comptime) Zig 的强大特性之一是在编译时执行代码:
comptime 关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 comptime var count: i32 = 0 ; fn compileTimeFunction ( comptime T: type , comptime size: usize ) type { return struct { data: [ size] T, pub fn get ( idx: usize ) T { return data[ idx] ; } } ; } const IntArray10 = compileTimeFunction( i32 , 10 ) ; var my_array: IntArray10 = undefined ;
类型作为参数 1 2 3 4 5 6 fn max ( comptime T: type , a: T, b: T) T { return if ( a > b) a else b; } const m1 = max( i32 , 5 , 10 ) ; const m2 = max( f64 , 3.14 , 2.71 ) ;
编译时反射 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const std = @import ( "std" ) ; fn printStructInfo ( comptime T: type ) void { const info = @typeInfo ( T) ; std. debug. print( "Type: {s}\n" , . { @typeName ( T) } ) ; if ( info == . Struct) { inline for ( info. Struct. fields) | field| { std. debug. print( " Field: {s} ({s})\n" , . { field. name, @typeName ( field. type ) , } ) ; } } }
内存管理 Zig 不提供垃圾回收,需要显式管理内存:
分配器模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const std = @import ( "std" ) ; pub fn main ( ) ! void { var gpa = std. heap. GeneralPurposeAllocator( . { } ) { } ; defer _ = gpa. deinit( ) ; const allocator = gpa. allocator( ) ; const arr = try allocator. alloc( i32 , 10 ) ; defer allocator. free( arr) ; for ( arr, 0 . . ) | * item, i| { item. * = @intCast ( i) ; } }
固定缓冲区分配器 1 2 3 4 5 6 var buffer: [ 1024 ] u8 = undefined ; var fba = std. heap. FixedBufferAllocator. init( & buffer) ; const allocator = fba. allocator( ) ; const slice = try allocator. alloc( u8 , 100 ) ;
Arena 分配器 1 2 3 4 5 6 7 var arena = std. heap. ArenaAllocator. init( std. heap. page_allocator) ; defer arena. deinit( ) ; const allocator = arena. allocator( ) ; _ = try allocator. alloc( u8 , 100 ) ; _ = try allocator. alloc( u8 , 200 ) ;
指针 基本指针 1 2 3 4 5 6 var x: i32 = 42 ; const ptr: * i32 = & x; ptr. * = 100 ; const maybe_ptr: ? * i32 = & x;
切片指针 1 2 3 4 5 6 var arr = [ _] i32 { 1 , 2 , 3 , 4 , 5 } ; const slice: [ ] i32 = & arr; const const_slice: [ ] const i32 = & arr; const str: [ : 0 ] const u8 = "hello" ;
多指针 1 2 3 4 5 extern fn c_function ( ptr: [ * c] const u8 ) void ;
与 C 语言互操作 Zig 可以无缝与 C 代码集成:
导入 C 头文件 1 2 3 4 5 6 7 8 const c = @cImport ( { @cInclude ( "stdio.h" ) ; @cInclude ( "stdlib.h" ) ; } ) ; pub fn main ( ) void { _ = c. printf( "Hello from C!\n" ) ; }
导出 Zig 函数给 C 1 2 3 4 5 6 7 8 export fn zig_add ( a: i32 , b: i32 ) i32 { return a + b; } export "C" fn zig_multiply ( a: i32 , b: i32 ) i32 { return a * b; }
类型映射 1 2 3 4 5 6 7 8 const c_int : c_int = 42 ; const c_char : c_char = 'a' ; const c_void : c_void = undefined ; const c_str: [ * c] const u8 = "hello" ; const zig_str: [ ] const u8 = std. mem. span( c_str) ;
泛型编程 使用 comptime 实现泛型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 fn Stack ( comptime T: type ) type { return struct { const Self = @This ( ) ; items: [ ] T, capacity: usize , len: usize = 0 , allocator: std. mem. Allocator, pub fn init ( allocator: std. mem. Allocator, capacity: usize ) ! Self { const items = try allocator. alloc( T, capacity) ; return Self{ . items = items, . capacity = capacity, . allocator = allocator, } ; } pub fn deinit ( self: * Self) void { self. allocator. free( self. items) ; } pub fn push ( self: * Self, item: T) ! void { if ( self. len >= self. capacity) return error.OutOfCapacity ; self. items[ self. len] = item; self. len + = 1 ; } pub fn pop ( self: * Self) ? T { if ( self. len == 0 ) return null ; self. len - = 1 ; return self. items[ self. len] ; } } ; } const IntStack = Stack( i32 ) ; var stack = try IntStack. init( allocator, 10 ) ; defer stack. deinit( ) ;
构建系统 Zig 自带构建系统,使用 build.zig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const std = @import ( "std" ) ; pub fn build ( b: * std. Build) void { const target = b. standardTargetOptions( . { } ) ; const optimize = b. standardOptimizeOption( . { } ) ; const exe = b. addExecutable( . { . name = "myapp" , . root_source_file = b. path( "src/main.zig" ) , . target = target, . optimize = optimize, } ) ; b. installArtifact( exe) ; const run_cmd = b. addRunArtifact( exe) ; run_cmd. step. dependOn( b. getInstallStep( ) ) ; const run_step = b. step( "run" , "Run the app" ) ; run_step. dependOn( & run_cmd. step) ; const unit_tests = b. addTest( . { . root_source_file = b. path( "src/main.zig" ) , . target = target, . optimize = optimize, } ) ; const run_unit_tests = b. addRunArtifact( unit_tests) ; const test_step = b. step( "test" , "Run unit tests" ) ; test_step. dependOn( & run_unit_tests. step) ; }
测试 Zig 内置测试框架:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const std = @import ( "std" ) ; const testing = std. testing; fn add ( a: i32 , b: i32 ) i32 { return a + b; } test "basic addition" { try testing. expect( add( 2 , 3 ) == 5 ) ; try testing. expectEqual( @as ( i32 , 5 ) , add( 2 , 3 ) ) ; } test "expect error" { const result = mightFail( false ) ; try testing. expectError( error.NotFound , result) ; } fn factorial ( n: u32 ) u32 { if ( n <= 1 ) return 1 ; return n * factorial( n - 1 ) ; }
运行测试:
包管理 Zig 使用 build.zig.zon 管理依赖:
1 2 3 4 5 6 7 8 9 10 . { . name = "myproject" , . version = "0.1.0" , . dependencies = . { . zap = . { . url = "https://github.com/zigzap/zap/archive/refs/tags/v0.1.0.tar.gz" , . hash = "1220..." , } , } , }
最佳实践 错误处理 :始终使用错误联合类型而非返回错误码内存管理 :使用 defer 确保资源释放编译时计算 :利用 comptime 进行泛型和元编程显式控制 :避免隐式行为,所有操作都应清晰可见与 C 互操作 :使用 Zig 逐步替换 C 代码总结 Zig 是一门设计精良的系统编程语言,主要特点包括:
显式优于隐式 :没有隐藏的控制流或内存分配编译时代码执行 :强大的元编程能力零成本抽象 :高性能的同时保持代码清晰C 语言互操作 :无缝集成现有 C 代码安全第一 :通过编译时检查和显式错误处理避免运行时错误Zig 适合系统编程、嵌入式开发、游戏引擎、编译器等需要高性能和精细控制的场景。
参考资源