Skip to content

Instantly share code, notes, and snippets.

@ssteinbach
Last active October 3, 2022 21:06
Show Gist options
  • Save ssteinbach/77c955ec7b752fb5a708b3d0bfbb637f to your computer and use it in GitHub Desktop.
Save ssteinbach/77c955ec7b752fb5a708b3d0bfbb637f to your computer and use it in GitHub Desktop.
Zig - struct with array slice member to be initialized later

Zig: Struct with Array Slice field

One pattern that seems to fall out of my brain when I return to Zig is having a struct with one array field that I want to assign to later. For example:

const StateData = struct {
  // I realize this is wrong, this is what my brain always wants to try first
  order: []burger=undefined,
};
const state:StateData = .{};
...
main(){
  //...
  state.order = _build_order(param1, param2);
  //...
}

The problems with this are:

  • if its a global scope, it needs to be compile time known
  • even if it is in main, it needs to be initialized to something before being created

The solution is:

  • use a 0 size array initialization
  • ...or use an optional

In this case, because an optional would impact all the places that touch this variable, and it naturally falls into something that is iterated over, a 0 size intializiation works well for me.

const std = @import("std");

var raw = std.heap.GeneralPurposeAllocator(.{}){};
pub const ALLOCATOR = raw.allocator();

const Burger = struct {
    num_toppings:i16,
};

const Order = struct {
    contents: []Burger,

    pub fn init(num_burgers: i32) Order {
        var result_order = std.ArrayList(Burger).init(ALLOCATOR);
        result_order.resize(num_burgers);

        var ind:i16 = 0;
        while (ind < num_burgers) : (ind += 1) {
            result_order.append( .{ .num_toppings = ind }) catch unreachable;
        }

        return .{
            .contents = result_order.items
        };
    }
};


const StateData = struct {
    // one line:
    // order: Order = .{ .contents = std.ArrayList(Burger).init(ALLOCATOR).items },
    order: Order = Order.init(0),
    other_state_data: i32 = 12,
    more_state_data: f32 = 3.14159,
};
var state:StateData = .{};

pub fn main() void {
    std.debug.print("order has {} burgers in it\n", .{ state.order.contents.len });

    // make a new "order" later in runtime
    state.order = Order.init(12);

    std.debug.print("order has {} burgers in it\n", .{ state.order.contents.len });
}

Once again, thanks to the helpful and friendly zig community on discord!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment