Len attribute from ArrayList items disappears after function return

Hey, I’m trying to learn Zig as my first system programming language.

I can’t quite get why len attribute disappears when I return items from a function but available inside the function.

const std = @import("std");

pub fn main() !void {
    var list = std.ArrayList(u16).init(std.heap.page_allocator);
    try list.append(42);
    std.debug.print("{d}", .{list.items.len});
    // 1

    const items = list.items;
    std.debug.print("{d}", .{items.len});
    // 1

    const res = data();
    std.debug.print("{d}", .{res.len});
    // ./main.zig:12:33: error:
    // type '@typeInfo(@typeInfo(@TypeOf(data)).Fn.return_type.?).ErrorUnion.error_set![]u16'
    // does not support field access

fn data() ![]u16 {
    var list = std.ArrayList(u16).init(std.heap.page_allocator);
    try list.append(42);
    return list.items;
    const res = try data();
1 Like

The error is that the return type of the function is not plainly []u16, but ![]u16, i.e. a union of an error set and the slice type.

Before you can use the slice, you need to unwrap it from the potential error. You can either use try data() or data() catch ..., refer to the manual: Documentation - The Zig Programming Language

But, also, you should probably return the std.ArrayList(u16) itself to the caller instead, so that it can be deinitialized properly later, or use toOwnedSlice() to release its contents so you can return those to the caller.


By the way, if this proposal is accepted Overhaul error handling control-flow and add error-stack intent · Issue #7812 · ziglang/zig · GitHub then I believe you’d get a much better error message. Something like

    const res = data();
error: unhandled error