为什么字符串数组需要使用中缀常量?

11

我正在缓慢学习zig,但是我不理解const及其如何与数组/类型交互 - 我正在查看https://ziglang.org/documentation/0.6.0/#Introduction,但他们经常用于字符串。

这段代码可以编译:

var n  = [_][]const u8 {"test 1", "test4", "test   6", "zz"};

没有 const 就会出错:

var n  = [_][] u8 {"test 1", "test4", "test   6", "zz"};

error: expected type '[]u8', found '*const [6:0]u8'

同样地,将const放在左侧也是同样的错误:

const n  = [_][]u8 {"test 1", "test4", "test   6", "zz"};

把const关键字放在中间,实际上是在指示编译器做什么?


5
在Zig语言中,字符串字面量是常量,不像C语言中你可以将一个字符串赋值给一个char*指针,然后改变字符串的内容。使用 var 可以从你的描述中推断出类型,但数组的描述必须与数组字面量匹配,这意味着必须使用 const 字符串。将 const 放在左侧只是表示你不会改变 n,但仍然描述了一个非常量项数组,并分配一个由常量字符串组成的数组。 - John Bayko
1个回答

14
在Zig中,const适用于声明中的下一个内容。
因此,[_][] u8是一个切片数组,而[_][] const u8是一个const u8切片数组。您的字符串字面量是*const [_:0]u8(指向的指针;这就是您的错误消息中*const [6:0] u8的来源),Zig可以将其强制转换为const u8切片。
以下是一些示例及其可变性: [_][]u8 - 所有内容都是可变的。
var move: [3][]u8 = undefined;
var ziga: [4]u8 = [_]u8{ 'z', 'i', 'g', 's' };
const zigs: []u8 = ziga[0..];
move[0] = zigs;
move[0][1] = 'a';
< p > [_][] const u8 - 这个切片是可变的,但其中的内容不可变。

var belong_to_us = [_][]const u8{ "all", "your", "base", "are" };
var bomb = [_][]const u8{ "someone", "set", "up", "us" };
belong_to_us = bomb;

但是
bomb[0][0] = 'x'; // error: cannot assign to constant

const [_][] const u8 - 这整个东西是不可变的。

const signal: [3][]const u8 = [_][]const u8{ "we", "get", "signal" };
const go: [3][]const u8 = [_][]const u8{ "move", "every", "zig" };
signal = go; // error: cannot assign to constant

然而,

const [_][]u8 - 这是一个字节片段的常量数组。

var what: [4]u8 = [_]u8{ 'w', 'h', 'a', 't' };
const signal: [3][]u8 = [_][]u8{ zigs, what[0..], zigs };
signal[0][1] = 'f'; // Legal!
signal[1] = zigs; // error: cannot assign to constant

那个最后的是一个可变切片的常量数组。

1
你能否解释一下*const [6:0]u8是什么,因为编译器找到了这个东西? - Neal Fultz
1
部分点赞是为了答案,部分是为了Zero Wing的参考 =D - Chris
1
@NealFultz 已更新。 - nmichaels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接