Tuple can't be destructured when being captured, right?

For example:

const std = @import("std");

fn foo() ?struct{bool, usize} {
    return .{true, 123};
}

pub fn main() !void {
    // This works.
    if (foo()) |v| {
        std.debug.print("{} {}\n", .{v[0], v[1]});
    }

    // This works too.
    {
        const b, const u = foo().?;
        std.debug.print("{} {}\n", .{b, u});
    }
    
    // This doesn't work.
    if (foo()) |b, u| {
        std.debug.print("{} {}\n", .{b, u});
    }
}

No you would need an extra line like my first example.

However with formatting you can use the placeholder syntax to do the destructuring if you don’t need the elements for anything else.

const std = @import("std");

fn foo() ?struct { bool, usize } {
    return .{ true, 123 };
}

pub fn main() !void {
    if (foo()) |v| {
        const b, const u = v;
        std.debug.print("{} {}\n", .{ b, u });
    }

    if (foo()) |v| {
        std.debug.print("{0} {1}\n", v);
    }

    if (foo()) |v| {
        std.debug.print("{1} {0}\n", v);
    }

    if (foo()) |v| {
        std.debug.print("{} {}\n", v);
    }
}

Output:

true 123
true 123
123 true
true 123
2 Likes

Yes, after some thinking, I think my expectation is not reasonable. :smiley:

1 Like

Another option would be to avoid the capture by using orelse with control flow instead (return or break):

const b, const u = foo() orelse return;
std.debug.print("{} {}\n", .{ b, u });
3 Likes