Payload pointer capture and struct method

I have some trouble using distreat/zig-csv and would like to know if I am doing something wrong with the way I use payload capture. Or if not, could someone please explain why I can not use payload capture in this case, and what are the conditions to be able to use it? Thank you for your help.

Here is an example of the code I am trying to run:

// pub fn init(allocator: Allocator, settings: Settings) Table {}
var table = csv.Table.init(allocator, csv.Settings.default());
defer table.deinit();

// pub fn parse(self: *Table, csv_data: []const u8) TableError!void {}
try table.parse(csv_data);

// pub fn getAllRows(self: Table) TableIterator {}
var rows = table.getAllRows();

// pub fn next(self: *TableIterator) ?RowIterator {}
while (rows.next()) |*row| {
    // pub fn get(self: *RowIterator, target_column_index: usize) TableError!RowItem {}
    const val = try row.*.get(0);
    _ = val;
}

And here is the corresponding error:

error: expected type '*iterators.RowIterator', found '*const iterators.RowIterator'
        const val = row.*.get(0).?.value;
                    ~~~~~^~~~
note: cast discards const qualifier
note: parameter type declared here
    pub fn get(self: *RowIterator, target_column_index: usize) TableError!RowItem {

I thought that using “payload pointer capture” instead of “payload capture” would let me discard the const qualifier, but I clearly thought wrong :slight_smile:

Until I better understand the payload capture concept, here is a current workaround that compiles fine:

var row = rows.next();
while (row != null) : (row = rows.next()) {
    const val = try row.?.get(0);
    _ = val;
}

I believe in while (rows.next()) rows.next() is a temporary and your code fails due to same reason rows.next().?.get(0); fails - you can’t get a mutable pointer to temporary

@yataro, thanks a lot for mentioning the concept of “temporary variables”, which I had not come across yet.
The 1st google search landed me on this “blog post from Karl Seguin” that explains this concept a bit deeper, and indeed, all I had to do was to explicitly assign the capture to a var for it to work:

while (rows.next()) |*row| {
    var data = row.*;
    const val = try data.get(0);
    _ = val;
}