返回文章列表

文章

关于Zig中的固定数组、字符串字面量、切片(slice)及 带哨兵数组

目录
  1. 下面从类型定义、内存布局、语言语义和典型场景四个方面,对 Zig 中的 固定数组、字符串字面量、切片(slice)及 带哨兵数组 进行梳理。
  2. 1. 固定长度数组 [N]T
  3. 定义与语义
  4. 示例
  5. 2. 带哨兵的固定数组 [N:sentinel]T
  6. 定义与语义
  7. 示例
  8. 3. 切片(Slice)[]T / []const T
  9. 定义与语义
  10. 示例
  11. 4. 字符串字面量
  12. 底层类型
  13. 与切片
  14. 用途
  15. 5. 小结对比
  16. 6. 典型使用场景

下面从类型定义、内存布局、语言语义和典型场景四个方面,对 Zig 中的 固定数组字符串字面量切片(slice)及 带哨兵数组 进行梳理。#

1. 固定长度数组 [N]T#

定义与语义#

  • 语法

const a: [4]u8 = [4]u8{1, 2, 3, 4}; // 或者让编译器推导长度: const b = [_]u8{10, 20, 30}; ```

  • 含义
    • 编译期已知长度 N,内存中占用正好 N × sizeof(T) 字节。
    • 不能动态增减长度;索引访问、切片必须在 0..N 范围内。
  • 用途
    • 用于存放固定大小的缓冲区,如加密密钥、协议包头、编译时大小已定的数据。
    • 在栈上分配,性能开销最低。

示例#

const header: [8]u8 = [8]u8{0xDE,0xAD,0xBE,0xEF,0,0,0,0};

2. 带哨兵的固定数组 [N:sentinel]T#

定义与语义#

  • 语法

const cs: [6:0]u8 = "hello"; // 5 字符 + 1 个 0 结尾 ```

  • 含义
    • 长度 N 表示有效元素数;在索引 N 处编译期自动保证一个 sentinel(如 0)。
    • 常用于 C 互操作时,等价于 C 的 char[N+1],保证字符串以 '\0' 结束。
  • 用途
    • 字符串字面量的底层类型。
    • 与 C 接口交互,传递以 null 结尾的缓冲区,无需手动加 0

示例#

const s: [6:0]u8 = "world";
// 内存是 ['w','o','r','l','d', 0]

3. 切片(Slice)[]T / []const T#

定义与语义#

  • 语法

const arr = [_]u8{1,2,3,4,5}; const sl1: []u8 = arr[1..4]; // 可变切片,len = 3,元素 [2,3,4] const sl2: []const u8 = arr[2..]; // 只读切片,len = 3,元素 [3,4,5] ```

  • 含义
    • 在运行时携带指针 ptr + 长度 len
    • 可对不同来源(静态数组、堆分配、栈分配、甚至 C 接口)获得统一视图。
  • 用途
    • 在函数间传递可变/只读区间,不复制底层数据。
    • 适合处理变长数据、流式读写、字节解析。

示例#

fn process(buf: []u8) void {
    // buf.len 动态决定,能够安全索引 0..buf.len-1
}

// 调用:从数组、从文件读入缓冲区、从网络接收等

4. 字符串字面量#

底层类型#

  • Zig 中的字符串字面量(例如 "hello Zig")本质上是 [len+1:0]const u8
  • 编译器为你在末尾附加一个 0 哨兵,保证 C 风格兼容。

与切片#

  • 你可以直接把它切片成 []const u8

const lit = "foo"; // 类型 [4:0]const u8 const sl: []const u8 = lit[0..3]; // len = 3,不包含末尾的 0 ```

  • 或者保留末尾哨兵:

const sl2: []const u8 = lit[0..]; // len = 4,最后是 0 ```

用途#

  • 作为程序中的只读常量,例如日志、提示文本、格式字符串。
  • 与 C 的 printfstrcpystrcmp 等接口无缝互操作。

5. 小结对比#

类型编译期长度运行期信息哨兵(终止标志)可变性用例
[N]T固定缓冲区、协议/结构体字段
[N:sentinel]T编译期自动附加C 互操作的 null-terminated 数据
[]T / []const Tptr + len取决于底层对象取决T可变通用变长视图、函数参数
字符串字面量是 (=len+1)含哨兵的固定数组末尾为 0否(只读)文本常量、格式化字符串

6. 典型使用场景#

  1. **固定数组 **[N]T
    • 密钥、GUID、MAC 地址、协议头字段等长度恒定的数据。
  2. **带哨兵数组 **[N:0]u8
    • 传递给 C API 的字符串缓冲区,确保有安全的 '\0' 终止符。
  3. **切片 []T / **[]const T
    • 在函数间传递数据段,不复制内容;读写网络帧、文件块、解析 CSV、JSON 等。
  4. 字符串字面量
    • 日志文本、错误提示、格式化模板,随时可转为切片或 []const u8 使用。

在 Zig 里,“数据”和“视图”是分开的,既保证了高性能(固定数组、哨兵数组),又带来了灵活性(切片、字符串字面量)。