Struct field not found using @field builtin function

Since we have a variable number of possible return types, I like to use helper functions to deduce these - to see examples of this, check out this thread: Implementing Generic Concepts on Function Declarations - #13 by AndrewCodeDev

Here’s an example that works using a helper function to deduce the type.

const std = @import("std");

const Info = struct {
    name: []const u8,
    age: u8,
};

pub fn InstanceFieldType(comptime T: type, comptime field_name: [] const u8) type {
    comptime var instance: T = undefined;
    return @TypeOf(@field(instance, field_name));
}

const InfoStorage = struct {
    const Self = @This();
    storage: [30]Info,
    pub fn readField(
        self: *Self,
        index: usize,
        comptime field_name: []const u8,
    ) InstanceFieldType(Info, field_name) {
        const storage_ref = &self.storage[index];
        return @field(storage_ref, field_name);
    }
};

pub fn main() void {
    var info: InfoStorage = undefined;
    info.storage[0] = .{ .name = "Jane", .age = 42 };
    std.debug.print("{d}\n", .{@field(&info.storage[0], "age")});
    std.debug.print("{d}\n", .{info.readField(0, "age")});
}

I’m also changing the self parameter type to be a pointer-to-self. It clarifies the intent that this is not supposed to be a copy.

– edited for for one more example –

You could also do this, but I don’t recommend it for the general case.

    pub fn readField(
        self: *Self,
        index: usize,
        comptime field_name: []const u8,
    ) @TypeOf(@field(self.storage[0], field_name)) { // adding &self.storage is optional here.
        const storage_ref = &self.storage[index];
        return @field(storage_ref, field_name);
    }

I don’t recommend it because accessing indices will at least require the array to have a size of 1. In your case, it’s kind of obvious it will work because you have 30 as the size. The reason I like the other method better is because it guarantees that there will be at least one instance available because we created it in the function itself.

1 Like