ArrayList as a struct field - how?

I want to have an ArrayList field in my structure, but can’t quite understand how to declare + initialize it:

const std = @import("std");

const ShaderManager = struct
{
    shader_progs: @TypeOf(std.ArrayList(u32)), // also tried std.ArrayList(u32)

    pub fn init(alloc8r: std.mem.Allocator) !ShaderManager
    {
        const sm = ShaderManager;
        sm.shader_progs = std.ArrayList(u32).init(alloc8r);
        for (0..10) |shdr_prog|
            try sm.shader_progs.append(shdr_prog);
        return sm;
    }

    pub fn deinit(self: *ShaderManager) void
    {
        // or, var iter = self.shader_progs.iterator();
        // for (iter) |shdr_prog|
        for (self.shader_progs.toSlice()) |shdr_prog|
            std.debug.print("Deleting shader program = {}\n", .{shdr_prog});
        self.shader_progs.deinit();
    }
};

pub fn main() !void
{
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const alloc8r = gpa.allocator();
    defer _ = gpa.deinit();

    var sm: ShaderManager = try ShaderManager.init(alloc8r);
    sm.deinit();
}

Looking into standard library sources, I can see that ArrayList is not a type, but a function that returns anonymous struct.
Is there a way to declare a variable of “ArrayList type” without initializing it?

I have read about Struct Naming, but don’t understand how do I apply it in my case. Trying shader_progs: std.ArrayList(u32), produces this confusing error:

error: struct 'arraylist_02.ShaderManager' has no member named 'shader_progs'
        sm.shader_progs = std.ArrayList(u32).init(alloc8r);
           ^~~~~~~~~~~~
shader_progs: std.ArrayList(u32),

is what you want.

The error you’re hitting is from this line:

const sm = ShaderManager;

which is assigning the type ShaderManager to the variable sm. So you’re essentially trying to do ShaderManager.shader_progs = std.ArrayList(u32).init(alloc8r).

If you want to create an instance of a ShaderManager you would need to do:

const sm = ShaderManager{};

This will also cause a compile error, but hopefully the new compile error will be more understandable.

3 Likes

My bad, missed {}.
So the solution then is -

const ShaderManager = struct
{
    shader_progs: std.ArrayList(u32),
    pub fn init(alloc8r: std.mem.Allocator) !ShaderManager
    {
        var sm = ShaderManager { .shader_progs = std.ArrayList(u32).init(alloc8r) };
        for (0..10) |shdr_prog|
            try sm.shader_progs.append(@intCast(shdr_prog)); // usize -> u32
        return sm;
    }
. . .
};

Okay, never mind the code below the cutline under this snippet, I’m keeping it for historical reasons - I hate when posts don’t make sense and don’t want to hide my mistakes.
I must have misread a forum post. Anyway, here’s a simple and logical way to iterate over the contents of ArrayList:

    pub fn print(self: ShaderManager) void
    {
        for (self.shader_progs.items) |shdr_prog|
            std.debug.print("Shader program = {}\n", .{shdr_prog});
    }
-------------------------------------------------------
---- !!! Bad / obsolete code below , do not use !!! ---
-------------------------------------------------------

Now I’m off to find a working way of iterating over my ArrayList, since

    pub fn print(self: ShaderManager) void
    {
        var iter = self.shader_progs.iterator();
        for (iter) |shdr_prog|
            std.debug.print("Shader program = {}\n", .{shdr_prog});
    }

gives me

arraylist_02.zig:18:37: error: no field or member function named 'iterator' in 'array_list.ArrayListAligned(u32,null)'
        var iter = self.shader_progs.iterator();
                   ~~~~~~~~~~~~~~~~~^~~~~~~~~
/home/archie/apps/zig/lib/std/array_list.zig:31:12: note: struct declared here                                                                
    return struct {
           ^~~~~~

And

        for (self.shader_progs.toSlice()) |shdr_prog|
            std.debug.print("Deleting shader program = {}\n", .{shdr_prog});

produces

arraylist_02.zig:29:31: error: no field or member function named 'toSlice' in 'array_list.ArrayListAligned(u32,null)'
        for (self.shader_progs.toSlice()) |shdr_prog|
             ~~~~~~~~~~~~~~~~~^~~~~~~~
/home/archie/apps/zig/lib/std/array_list.zig:31:12: note: struct declared here
    return struct {
           ^~~~~~
1 Like

Access items directly.

2 Likes

I’ve made a few posts too that I rolled my eyes at when I realized the answer after I clicked submit. Happens to all of us.

Also… for people trying to learn, they may have the same questions you have but know much less. So these examples can actually be valuable to have.

We’re all just thinking out loud, after all :slight_smile:

Yeah, that’s what I did.
Thank you for replying!

That’s what I was trying to do :slightly_smiling_face: