Zig 基本语法
Zig 是一种新的编程语言,设计简单、高效,并且直接与 C 语言兼容。
下面是一些 Zig 的基本语法介绍,帮助你快速上手。
Zig 代码文件的后缀名为 .zig。
第一个 Zig 程序
我们先来看看 Zig 的 "Hello, World!" 程序。
我们先来初始化一个 zig 项目:
mkdir hello-world cd hello-world zig init
然后在该项目下创建 hello.zig 文件,代码如下:
实例(hello.zig 文件)
pub fn main() void {
const stdout = std.io.getStdOut().writer();
stdout.print("Hello, World!\n", .{}) catch {};
}
代码解析:
1、导入标准库:
const std = @import("std");
这行代码导入了 Zig 的标准库,类似于 C 语言中的 #include <stdio.h>。
2、定义 main 函数:
pub fn main() void {
这是程序的入口点。
pub 关键字表示这个函数是公开的,fn 关键字用于定义函数,main 是函数名,() void 表示这个函数不接受任何参数,并且返回类型是 void(无返回值)。
3、获取标准输出:
const stdout = std.io.getStdOut().writer();
这行代码获取标准输出(通常是终端),并将其转换为一个写入器(writer())。
4、打印 "Hello, World!":
stdout.print("Hello, World!\n", .{}) catch {};
使用 print 方法将字符串 "Hello, World!\n" 写入标准输出。
.{} 是一个空的关联数组,用于传递可选参数。
catch 关键字用于捕获并处理可能发生的异常,这里简单地将其忽略。
5、错误处理:
catch {};
catch 关键字用于捕获并处理可能发生的异常。
在这里,我们只是简单地捕获它,但没有做任何处理({} 表示空的代码块)。
这个程序非常简单,但它展示了 Zig 语言的一些基本特性,比如函数定义、标准库的使用、异常处理等。要运行这个程序,你需要安装 Zig 编译器,然后使用以下命令:
zig build-exe hello.zig
这会生成一个可执行文件(通常是 hello),你可以通过运行它来查看输出。
在终端中运行编译后的脚本:
./hello
这将输出 "Hello, World!"。
标识符
在 Zig 语言中,标识符是用来命名变量、函数、类型等的名称。
以下是一些关于 Zig 标识符的规则和特性:
-
字母和数字:标识符可以包含字母(A-Z 和 a-z)、数字(0-9)和下划线(_)。
-
开头字符:标识符必须以字母或下划线开头,不能以数字开头。
-
大小写敏感:Zig 是一种区分大小写的语言,这意味着
Variable
和variable
是两个不同的标识符。 -
关键字和保留字:一些特定的单词在 Zig 中是保留的,不能用作标识符。例如
fn
(函数)、struct
(结构体)、if
(条件语句)等。 -
命名约定:
- 驼峰命名法:通常使用驼峰命名法来命名标识符。例如,函数名
calculateSum
,类型名Person
。 - 下划线命名法:在一些情况下,尤其是在与 C 语言交互时,可能需要使用下划线命名法。例如
calculate_sum
。
- 驼峰命名法:通常使用驼峰命名法来命名标识符。例如,函数名
-
可选类型:Zig 语言中有一个特殊的类型
?T
,表示一个类型为T
的可选值。这在处理可能为空的值时非常有用。 -
编译时常量:在标识符前使用
comptime
关键字,可以表示该标识符是一个编译时常量。 -
错误类型:使用
error
关键字可以定义错误类型,例如:pub fn openFile(path: []const u8) !void { // ... }
-
类型后缀:在类型名称后使用
_t
后缀是 C 语言的习惯,在 Zig 中也可以这样做,但不是必需的。
保留关键词
以下是 Zig 语言的一些保留关键词:
Keywords | Description |
---|---|
align | 指定变量或类型对齐字节数 |
allowzero | 允许指针指向空值 |
and | 逻辑与操作 |
asm | 内联汇编块 |
async | 异步函数声明 |
await | 等待异步操作完成 |
break | 跳出最近的循环或作用域 |
callconv | 调用约定 |
const | 定义常量 |
continue | 继续下一次循环迭代 |
defer | 延迟执行语句,直到作用域退出 |
else | 条件语句的否定分支 |
enum | 枚举类型 |
errdefer | 错误发生时的延迟执行语句 |
error | 错误类型定义 |
export | 导出符号 |
fn | 函数定义 |
for | 遍历循环 |
if | 条件语句 |
inline | 内联函数 |
linksection | 指定链接器的节 |
noalias | 指针不能被其他指针别名 |
noasync | 禁止函数内使用 await |
noinline | 阻止函数内联 |
null | 空值 |
or | 逻辑或操作 |
packed | 取消结构体填充 |
pub | 公开(public)访问级别 |
return | 从函数返回 |
struct | 结构体类型定义 |
suspend | 异步函数的挂起点 |
switch | 多路分支选择语句 |
test | 测试代码块 |
threadlocal | 线程局部变量 |
try | 尝试执行表达式,可能产生错误 |
union | 联合体类型定义 |
usingnamespace | 使用指定的命名空间 |
var | 定义变量 |
void | 无类型,常用于函数无返回值 |
while | 循环语句 |
基本语法
1. 变量与常量
在 Zig 中,变量使用 var 关键字定义,常量使用 const 关键字定义。
const x: i32 = 10; // 定义一个整数常量 x,值为 10 var y: f64 = 3.14; // 定义一个浮点数变量 y,值为 3.14
2. 函数
函数使用 fn 关键字定义,并指定返回类型。
const std = @import("std"); fn add(a: i32, b: i32) i32 { return a + b; } pub fn main() void { const result = add(3, 4); std.debug.print("Result: {}\n", .{result}); }
3. 条件语句
使用 if 和 else 来实现条件逻辑。
const std = @import("std"); pub fn main() void { const number = 10; if (number > 0) { std.debug.print("Number is positive\n", .{}); } else { std.debug.print("Number is not positive\n", .{}); } }
4. 循环
Zig 支持 while 和 for 循环。
const std = @import("std"); pub fn main() void { var i: i32 = 0; while (i < 5) : (i += 1) { std.debug.print("i: {}\n", .{i}); } const array = [5]i32{1, 2, 3, 4, 5}; for (array) |item| { std.debug.print("item: {}\n", .{item}); } }
5. 结构体
Zig 使用 struct 来定义结构体。
const std = @import("std"); const Point = struct { x: i32, y: i32, }; pub fn main() void { const p = Point{ .x = 10, .y = 20 }; std.debug.print("Point: ({}, {})\n", .{p.x, p.y}); }
6. 错误处理
Zig 使用错误枚举类型和 try 关键字进行错误处理。
const std = @import("std"); const Error = error{ FileNotFound, }; fn readFile(path: []const u8) !void { // 模拟一个可能失败的操作 if (path == "invalid") { return Error.FileNotFound; } // 其他操作 } pub fn main() void { if (readFile("invalid") catch |err| switch (err) { Error.FileNotFound => { std.debug.print("Error: File not found\n", .{}); }, }) | _ | { std.debug.print("File read successfully\n", .{}); } }