文章
关于Zig中的固定数组、字符串字面量、切片(slice)及 带哨兵数组
目录
下面从类型定义、内存布局、语言语义和典型场景四个方面,对 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'结束。
- 长度 N 表示有效元素数;在索引 N 处编译期自动保证一个
- 用途
- 字符串字面量的底层类型。
- 与 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 的
printf、strcpy、strcmp等接口无缝互操作。
5. 小结对比#
| 类型 | 编译期长度 | 运行期信息 | 哨兵(终止标志) | 可变性 | 用例 |
|---|---|---|---|---|---|
[N]T | 是 | 无 | 无 | 否 | 固定缓冲区、协议/结构体字段 |
[N:sentinel]T | 是 | 无 | 编译期自动附加 | 否 | C 互操作的 null-terminated 数据 |
[]T / []const T | 否 | ptr + len | 取决于底层对象 | 取决T可变 | 通用变长视图、函数参数 |
| 字符串字面量 | 是 (=len+1) | 含哨兵的固定数组 | 末尾为 0 | 否(只读) | 文本常量、格式化字符串 |
6. 典型使用场景#
- **固定数组 **
[N]T- 密钥、GUID、MAC 地址、协议头字段等长度恒定的数据。
- **带哨兵数组 **
[N:0]u8- 传递给 C API 的字符串缓冲区,确保有安全的
'\0'终止符。
- 传递给 C API 的字符串缓冲区,确保有安全的
- **切片
[]T/ **[]const T- 在函数间传递数据段,不复制内容;读写网络帧、文件块、解析 CSV、JSON 等。
- 字符串字面量
- 日志文本、错误提示、格式化模板,随时可转为切片或
[]const u8使用。
- 日志文本、错误提示、格式化模板,随时可转为切片或
在 Zig 里,“数据”和“视图”是分开的,既保证了高性能(固定数组、哨兵数组),又带来了灵活性(切片、字符串字面量)。