字符串字面量 (String Literals)
字符串字面量和 Unicode 代码点字面量 (String Literals and Unicode Code Point Literals)
字符串字面量是指向以 null 结尾的字节数组的常量单项指针(constant single-item Pointers)。字符串字面量的类型既编码了长度,也编码了它们以 null 结尾的事实,因此它们可以被强制转换为切片(Slices)和以 null 结尾的指针(Null-Terminated Pointers)。对字符串字面量进行解引用(Dereferencing)会将它们转换为数组(Arrays)。
因为 Zig 源代码是 UTF-8 编码的,所以在源代码中的字符串字面量内出现的任何非 ASCII 字节都会将其 UTF-8 含义带入 Zig 程序的字符串内容中;编译器不会修改这些字节。可以使用 \xNN 符号将非 UTF-8 字节嵌入到字符串字面量中。
对包含非 ASCII 字节的字符串进行索引会返回单个字节,无论其是否为有效的 UTF-8。
Unicode 代码点字面量具有 comptime_int 类型,与整型字面量相同。所有转义序列在字符串字面量和 Unicode 代码点字面量中均有效。
文件: string_literals.zig
const print = @import("std").debug.print;
const mem = @import("std").mem; // 将用于比较字节
pub fn main() void {
const bytes = "hello";
print("{}\n", .{@TypeOf(bytes)});
print("{d}\n", .{bytes.len});
print("{c}\n", .{bytes[1]});
print("{d}\n", .{bytes[5]});
print("{c} == \x65\n", .{'e' == '\x65'});
print("{d}\n", .{'\u{1f4a9}'});
print("{d}\n", .{'\U{1F4A9}'});
print("{u}\n", .{'⚡'});
print("{}
", .{mem.eql(u8, "hello", "h\x65llo")});
print("{}
", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")});
const invalid_utf8 = "\xff\xfe"; // 使用 \xNN 符号可以使用非 UTF-8 字符串。
print("0x{x}\n", .{invalid_utf8[1]});
print("0x{x}\n", .{"💯"[1]});
}
Shell:
$ zig build-exe string_literals.zig
$ ./string_literals
*const [5:0]u8
5
e
0
true
128169
128175
⚡
true
true
0xfe
0x9f
另请参阅:
- Arrays (数组)
- Source Encoding (源文件编码)
转义序列 (Escape Sequences)
| 转义序列 | 名称 |
|---|---|
\n | 换行符 (Newline) |
\r | 回车符 (Carriage Return) |
\t | 制表符 (Tab) |
\\ | 反斜杠 (Backslash) |
\' | 单引号 (Single Quote) |
\" | 双引号 (Double Quote) |
\xNN | 十六进制 8 位字节值(2 位数字) |
\u{NNNNNN} | 十六进制 Unicode 标量值 UTF-8 编码(1 位或多位数字) |
注意:最大有效 Unicode 标量值为 0x10ffff。
多行字符串字面量 (Multiline String Literals)
多行字符串字面量没有转义字符,可以跨越多行。要开始多行字符串字面量,请使用 \\ 标记。就像注释一样,字符串字面量一直持续到行尾。行尾本身不包含在字符串字面量中。但是,如果下一行以 \\ 开头,则会追加一个换行符,并且字符串字面量继续。
文件: multiline_string_literals.zig
const hello_world_in_c =
\\#include <stdio.h>
\\
\\int main(int argc, char **argv) {
\\ printf("hello world\n");
\\ return 0;
\\}
;