#'optional while' exit first iteration
1 messages · Page 1 of 1 (latest)
you want it to run some other code when next returns null, but then continue back and check next again?
what is the condition for it leaving this loop
while (true) {
if (arg_iterator.next()) ...
else {
// other code
}
}
could work
If on the first next call it returns null, I still want to exit the loop but run a special case
in my case telling the user to specify an argument
you can just call next before the while loop
So putting it in a variable and mutating it in the loop?
Hmm for some reason I thought that would be way more code
var maybe_next_arg = arg_iterator.next();
if (maybe_next_arg == null) {
try stderr.print("Specify a parameter", .{});
try stderr.flush();
return 1;
}
while (maybe_next_arg) |next_arg| {
// ...
maybe_next_arg = arg_iterator.next();
}
This works, but it checks maybe_next_arg twice.
Is that fine / what you meant, or is there a better way
Btw I'm completely fine with this but knowing Zig maybe there's some syntax/pattern I missed
The else from while always runs at the last iteration of the while loop, if I'm reading and using it correctly
That means it would trigger if e.g. the 10th call to next returns null. "Specify a parameter" should only show if there is no args in the iterator, just like in the snippet
while (arg_iterator.next()) |next_arg| {
// ...
} else {
try stderr.print("Specify a parameter", .{}); // always runs, even if there was a previous parameter
try stderr.flush();
return 1;
}
Okay, I'm understanding your use case a bit more. You're right, that wouldn't be appropriate.
This seems like a pretty good pattern to me. One thing I would change (assuming you're using a std lib iterator) is to use peek() for the first arg, and then next() for the rest of the args.
could you do something like
const maybe = arg_iterator.first();
if (maybe != null) {
...
}
while (arg_iterator) |arg| : (arg_iterator.next()) {
...
}
Actually, I just realized not all the iterators have peek(), never mind lol
Haha was about to check if I looked over it
Would've been appropriate yeah
Uh I'm not so sure about this syntax, arg_iterator is the std ArgIterator
var maybe_next_arg = arg_iterator.next();
if (maybe_next_arg == null) {
try stderr.print("Specify a parameter", .{});
try stderr.flush();
return 1;
}
while (maybe_next_arg) |next_arg| : (maybe_next_arg = arg_iterator.next()) {
// ...
}
It could be this indeed, but it has the same problem
In that the first maybe_next_arg is being checked twice, once in the if statement and once in the first run of the while loop
you could
var ran = false;
while (iter.next()) |arg| {
ran = true;
//...
}
if (!ran) //...
if you want to do it beforehand
you can just copy the body of the loop into an if
if (iter.next()) |arg| {
//do arg stuff
} else {
//...
}
while (iter.next()) |arg| {
// also do arg stuff
}
that doesnt check it twice
Fair, thanks for the suggestions! I realized a do {} while would do the job nicely here, if Zig had it:
var maybe_next_arg = arg_iterator.next();
if (maybe_next_arg == null) {
try stderr.print("Specify a parameter", .{});
try stderr.flush();
return 1;
}
do {
// Doesn't check maybe_next_arg the first iteration
} while (maybe_next_arg) : (maybe_next_arg = arg_iterator.next());