activity-simplified.zig:18:23: error: type '[]activity-simplified.Activity.Step' does not support array initialization syntax
.steps = .{
~^
activity-simplified.zig:18:23: note: inferred array length is specified with an underscore: '[_]activity-simplified.Activity.Step'
If i change the declaration of the steps field from []Step to [1]Step, the program works correctly.
Careful though if you return an Activity from a function, the .steps slice points to separate data on the stack and that will be gone upon function exit so you’ll get a dangling pointer (one important reason why I heavily prefer fixed-capacity nested arrays instead of slices in such situations - unfortunately Zig lacks some syntax sugar which would make working with nested arrays just as convenient as with slices).
PS:
If i change the declaration of the steps field from []Step to [1]Step
…you’re turning the slice (e.g pointer to an external array) into a nested array that lives inside the struct. Very important difference
The slice syntax is a bit deceptive in that it looks and feels like an array, not like a pointer. But you need to pay the same attention to slices as with pointers, a slice is essentially a fat pointer with a (multi-item-)pointer and length inside.
Hmm true, you need to change the steps declaration to const:
steps: []const Step,
…that does indeed look a bit weird though… because it would mean that the steps slice content can never be mutable… but it’s the same thing the CreateModuleOptions struct does in the build.zig example I pasted:
The problem might be that an array literal is const and cannot be coerced to a var, which kinda makes sense in a way… a little detail which I haven’t noticed yet … but yet another advantage of nested fixed-capacity arrays
No that doesn’t help, since it’s the array literal on the right side of the steps assignment which is the problem. This basically forces everything else to be const.
You can definitely make variable array literals. I’m not sure where the syntax is getting caught up wrong, but i found that first declaring the array as a var, and then taking a reference to it works.
As a related fun fact, this is the only way i know of to make comptime known variable string ‘literals’, as anything between quotes will be constant (and put in the read only section of data), you have to use array literal syntax to create a string that can be modified in place.
This doesn’t work because what is being declared as variable isn’t the underlying data, but the pointer. So you get a variable pointer to constant data. To get a pointer to varible data you must first declare the data to be var.