I am too stupid ig, would appreciate some help.
const ABC = [_][]const u8{
"one", "two", "three",
};
fn returnABC() [][]const u8 {
return ABC;
}
test "testing returnABC" {
try testing.expect(returnABC() == ABC);
}
Why is a simple code like this failing with error
error: array literal requires address-of operator (&) to coerce to slice type '[][]const u8'
Adding & worsens the error, I dont properly understand the pointer situation in zig, Im not getting anything related on google
Here’s one way of doing this:
const std = @import("std");
const ABC = [_][]const u8{
"one", "two", "three",
};
fn returnABC() []const []const u8 {
return ABC[0..];
}
test "testing returnABC" {
try std.testing.expect(std.meta.eql(returnABC(), ABC[0..]));
}
1 Like
Note that [_][]const u8
and [][]const u8
are completly different things, despite looking similar.
Generally [_]T
is an array of compile-time known length.
[]T
is a slice, which is a pointer to an array of runtime-known length.
A slice is basically a struct{ptr: [*]T, len: usize}
with some syntactic sugar.
Now to make an array into a pointer to an array, you need to use the address-of operator &
.
In your case &ABC
. This will give you a *const [3][]const u8
.
This can coerce to a slice []const []const u8
Now your second problem is const
ness. You said that ABC
is const
.
Therefore its pointer, &ABC
must be pointer to constant memory.
You however want to a [][]const u8
which is a mutable(!) slice of []const u8
.
Now your third problem is that ==
is not available for slices. You can however compare it element-wise:
const a = returnABC();
try std.testing.expect(a.ptr == &ABC and a.len == ABC.len);
Or for convenience you can use std.meta.eql
3 Likes