10

I am learning zig slowly, but I don't understand const and how it interacts with arrays/types - I'm going through https://ziglang.org/documentation/0.6.0/#Introduction but they use const a lot for strings.

This compiles:

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

Without the const is an error:

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

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

similarly, putting const on the left is the same error:

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

What is putting the const keyword in the middle that way actually directing the compiler to do?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Neal Fultz
  • 9,282
  • 1
  • 39
  • 60
  • 5
    String literals in zig are constant, unlike C where you can assign a string to a char * pointer, then change the contents of the string. `var` is deducing the type from your description, but the array description must match the array literal, and that means `const` strings. Putting `const` on the left just means you're not going to change `n`, but it's still describing an array of non-const items, and assigning an array of const strings. – John Bayko Nov 04 '20 at 17:43

1 Answers1

13

In Zig, const applies to the next thing in the declaration.

So [_][] u8 is an array of u8 slices, while [_][] const u8 is an array of slices of const u8. Your string literals are *const [_:0]u8 (pointer to null-terminated array of u8; that's where the *const [6:0] u8 in your error message is from), which Zig can coerce to slices of const u8.

Some examples and how mutable they are:

[_][]u8 - Everything is mutable.

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';

[_][] const u8 - The slice is mutable, but things in it are not.

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

but

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

const [_][] const u8 - The whole thing is immutable.

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

However,

const [_][]u8 - This is a const array of slices of 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

That last one is a constant array of slices of mutable u8.

nmichaels
  • 49,466
  • 12
  • 107
  • 135