How to create an arrray of strings

Hi,

I just started to learn zig. But I cannot figure out how to create an array of strings.

I would like to write something like:

const someStrings: []const [3:0]u8 = .{
    "abc",
    "def",
    "ghi",
};

I tried with multiple variant of the type like [][]const u8 or [_]const [3:0]u8

But I just cannot figure out how to get passed this compiler error:

const [3:0]u8’ does not support array initialization syntax

Is it even possible to create a const array of string at compile time?

Thanks in advance for your help.

The following is a example of slice and array:

const std = @import("std");

pub fn main() !void {
    const slice = &.{"abc", "def", "ghi"};
    const array = [_][]const u8{"abc", "def", "ghi"};

    std.debug.print("len: {}, {}\n", .{slice.len, array.len});
}

Welcome to ziggit !

2 Likes

The type of a string literal is a const pointer to a sentinel-terminated array of bytes, or *const [N:0]u8. Since the length is encoded in the type, it’s not feasible to create an array of these pointer types directly unless they are all the same length. The strings in your example are all the same length, so you can create an array using the full type of the strings like so:

const array_of_fully_qualified_string_literals = [_]*const [3:0]u8{
    "abc",
    "def",
    "ghi",
};

However, such pointers-to-arrays will coerce to a slice type, and it’s common to coerce them to []const u8 (or [:0]const u8 if you care about sentinel termination):

const str: []const u8 = "foo";

So, for an array of arbitrary strings, you can make the element type []const u8:

const array_of_strings = [_][]const u8{ "foo", "something" };

If you take the address of that array, then it, too, will coerce to a slice, so you can also do:

const array_of_strings = [_][]const u8{ "foo", "something" };
const slice_of_strings: []const []const u8 = &array_of_strings;

The shorthand .{} initialization can make things more convenient still, as long as the destination type is specified:

const slice_of_strings: []const []const u8 = &.{ "foo", "something" };

For completeness, note that @TypeOf(&.{ "foo", "something" }) is actually a tuple:

*const struct { comptime *const [3:0]u8 = "foo", comptime *const [9:0]u8 = "something" }

but it can be coerced to a []const []const u8

4 Likes

Thanks to both of you for your answers. It makes sense, and I managed to fix my problem.

1 Like