Skip to content

Day 4: Zig基本语法概述

欢迎来到第四天!今天我们将全面了解Zig的基本语法。Zig的设计哲学之一是简洁与一致性,避免C++那样的语法复杂性。它的语法在很多方面与C相似,这为有C/C++/Java等背景的开发者降低了学习门槛。同时,Zig也引入了许多现代化的改进,使得代码更具可读性和可维护性。

在Zig中,几乎所有东西都是表达式(Expression),这意味着它们会返回一个值。

  • 语句(Statement): 一个语句是一段执行操作但不返回值的代码。在Zig中,真正的语句很少,主要包括变量声明、赋值等。语句以分号 ; 结尾。

    var x: i32 = 10; // 变量声明语句
    x = 20; // 赋值语句
  • 表达式(Expression): 一个表达式是一段求值后会产生一个值的代码。例如 2 + 2 是一个表达式,它的值是 4。if、while、代码块 {} 等在Zig中都是表达式。

    const y = if (x > 10) 1 else 0; // if是表达式,y的值将是1或0
  • 分号: 分号用于分隔语句。在代码块的最后一行,如果它是一个表达式,可以省略分号,该表达式的值将成为整个代码块的值。

    const z = blk: {
    const a = 1;
    const b = 2;
    break :blk a + b; // 使用break将值传出块
    }; // z的值是3

良好的注释是代码可读性的关键。Zig支持多种注释风格:

  • 单行注释 //: 从 // 开始,直到行尾的所有内容都会被编译器忽略。

    // 这是一个单行注释
    const a = 1; // 也可以在代码后面
  • 文档注释 ///: 这是特殊的单行注释,用于为它下面的代码(通常是函数、变量、类型等)生成文档。

    /// 这是一个文档注释,描述下面的函数
    /// 它接受一个整数并返回它
    pub fn identity(x: i32) i32 {
    return x;
    }
  • 多行注释 /* ... */: Zig不支持C风格的多行注释 /* ... */。这个决定是为了简化语法解析和避免嵌套注释带来的问题。你只需要使用多个 // 即可。

Zig社区推崇统一的代码风格,并通过 zig fmt 工具来强制执行。

  • zig fmt: 这个工具会解析你的代码并重新格式化,以符合官方标准。建议在每次提交代码前都运行 zig fmt。

    Terminal window
    zig fmt your_file.zig
    zig fmt . # 格式化当前目录下所有.zig文件
  • 命名规范:

    • 变量和函数名使用 snake_case(蛇形命名法),例如 my_variable。
    • 类型名使用 PascalCase(帕斯卡命名法),例如 MyType。
    • 顶层常量的文件名使用 SCREAMING_SNAKE_CASE(大写蛇形命名法),例如 MAX_CONNECTIONS。
  • 标识符(Identifier): 标识符是给变量、函数、类型等起的名字。它们可以包含ASCII字母、数字和下划线,但不能以数字开头。Zig也支持Unicode标识符,这意味着你可以用非ASCII字符(如中文)来命名,但这在实践中不常用。

    const π = 3.14159; // 合法的Unicode标识符
  • 保留字(Keywords): Zig有一系列保留字,它们有特殊的语法含义,不能用作标识符。例如 const, var, fn, if, else, return 等。完整的列表可以在官方文档中找到。

下面的例子展示了如何在一个块表达式中执行多行计算,并返回最终结果。

const std = @import("std");
pub fn main() !void {
const a = 10;
const b = 20;
const result = blk: {
std.debug.print("Calculating in a block...\n", .{});
const sum = a + b;
const product = a * b;
// 块的最后一行表达式是返回值
break :blk sum + product;
};
std.debug.print("Result is: {d}\n", .{result}); // 输出: Result is: 230
}

创建一个名为 calculator.zig 的文件。在文件中,使用注释来规划一个简单的命令行计算器的草稿。

  1. 使用 /// 文档注释来描述整个文件的目标。
  2. 使用 // 单行注释来列出需要实现的功能步骤(例如:读取输入、解析数字、执行运算、打印结果)。
  3. 定义几个 const 变量,并为它们添加行尾注释,解释其用途。

这个练习的重点是熟练使用不同的注释类型,而不是实现功能。

问:如果我忘记写分号会怎么样?

答:Zig的编译器会给出一个明确的错误信息。例如,如果你在两条语句之间忘记了分号,编译器会提示 “expected ’;’ after statement”。相比C语言,Zig的错误提示通常更友好和精确。

问:为什么Zig不支持 /* ... */ 多行注释?

答:这是Zig设计者为了简化语言而做出的权衡。移除多行注释可以避免一些解析上的歧义(例如嵌套注释 /* a /* b */ c */),并鼓励使用更清晰的单行注释。同时,现代代码编辑器可以轻松地添加或删除多行 // 注释,使得这个功能在实践中并非不可或缺。

今天我们学习了Zig语法的基本构成要素。核心要点是:几乎一切都是表达式,代码风格由 zig fmt 统一,注释简洁而功能明确。这些设计共同构成了一门既像C一样底层,又具备现代语言清晰度和表现力的编程语言。

明天,我们将深入探讨Zig的基石——变量和基本数据类型。