字符串字面量 (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

另请参阅:

转义序列 (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;
    \\}
;

另请参阅: