Zig 基本语法

Zig 是一种新的编程语言,设计简单、高效,并且直接与 C 语言兼容。

下面是一些 Zig 的基本语法介绍,帮助你快速上手。

Zig 代码文件的后缀名为 .zig


第一个 Zig 程序

我们先来看看 Zig 的 "Hello, World!" 程序。

我们先来初始化一个 zig 项目:

mkdir hello-world
cd hello-world
zig init

然后在该项目下创建 hello.zig 文件,代码如下:

实例(hello.zig 文件)

const std = @import("std");

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 标识符的规则和特性:

  1. 字母和数字:标识符可以包含字母(A-Z 和 a-z)、数字(0-9)和下划线(_)。

  2. 开头字符:标识符必须以字母或下划线开头,不能以数字开头。

  3. 大小写敏感:Zig 是一种区分大小写的语言,这意味着 Variablevariable 是两个不同的标识符。

  4. 关键字和保留字:一些特定的单词在 Zig 中是保留的,不能用作标识符。例如 fn(函数)、struct(结构体)、if(条件语句)等。

  5. 命名约定

    • 驼峰命名法:通常使用驼峰命名法来命名标识符。例如,函数名 calculateSum,类型名 Person
    • 下划线命名法:在一些情况下,尤其是在与 C 语言交互时,可能需要使用下划线命名法。例如 calculate_sum
  6. 可选类型:Zig 语言中有一个特殊的类型 ?T,表示一个类型为 T 的可选值。这在处理可能为空的值时非常有用。

  7. 编译时常量:在标识符前使用 comptime 关键字,可以表示该标识符是一个编译时常量。

  8. 错误类型:使用 error 关键字可以定义错误类型,例如:

    pub fn openFile(path: []const u8) !void {
        // ...
    }
  9. 类型后缀:在类型名称后使用 _t 后缀是 C 语言的习惯,在 Zig 中也可以这样做,但不是必需的。

保留关键词

以下是 Zig 语言的一些保留关键词:

KeywordsDescription
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", .{});
    }
}