First of all []const []const f64 isn’t a 2D array it is a 2D slice, the memory layout of 2D slices is a lot more complicated than of 2D or ND arrays, because for multi dimensional slices you need the memory for all the slices (another downside is that for rectangular/cuboid shaped data you repeat the same length over and over again, and another downside is the slice-indirections and the potentially non-contiguous memory layout).
For arrays it is much easier because with arrays the length information is compile time known and thus it just boils down to calculating the correct location for a coordinate.
With Slices you have the outer most slice, which then contains more slices, which contain more slices, which …
In the 2D case it looks like your first example.
The second example doesn’t work because you are trying to create a slice where you can modify the slices it contains (so that they point to somewhere else or have a different length) (It seems unlikely to me that that is actually what you want to do, but that is what the type you are aiming for allows you to do)
This is taking the address of a temporary (the array literal doesn’t have a var or const variable where it is stored) and in Zig temporary values are always treated as constants, which is why taking its address gives you a pointer to a constant and this constant pointer can only be coerced to a const slice, which is why your first example works and the second doesn’t.
slices.zig:5:30: error: expected type '[][]const f64', found '*const [2][]const f64'
const a: [][]const f64 = &[_][]const f64{
^
slices.zig:5:30: note: cast discards const qualifier
If you want to make it work you need to store the array in a var and then take the pointer:
const std = @import("std");
pub fn main() !void {
const b: []const f64 = &[_]f64{ 1, 2 };
var data = [_][]const f64{
b,
b,
};
const a: [][]const f64 = &data;
std.debug.print("a: {any}\n", .{a});
}
I think it would be good if you describe what you are actually trying to do with that 2D slice, it is possible that you are actually better off with a completely different type, depending on what you are doing with it in that function you are using.
Recommended related reading: