Seems to me like you could just use @min
and @max
to get the lower and upper bound:
fn sample(h: u32, w: u32) u32 {
const l = @min(w, h);
const h = @max(w, h);
// ...
}
If these are width and height and you are switching them, then they aren’t really used like width and height in the algorithm and more like bounds, so having to give them new names seems appropriate.
In this particular case, I think if expression with destructuring and new variables is a nice solution:
const std = @import("std");
fn sample(h: u32, w: u32) u32 {
const l, const u = if (w > h) .{ h, w } else .{ w, h };
return u - l;
}
pub fn main() !void {
std.debug.print("sample(20, 10) = {}\n", .{sample(20, 10)});
std.debug.print("sample(10, 20) = {}\n", .{sample(10, 20)});
}
But something like the following doesn’t work, because of aliasing (it doesn’t introduce a temporary variable and the assignment to a and b are two separate steps), so if you use destructuring+if to swap make sure that the destination variables are independent from the ones in the if:
pub fn main() !void {
var a: u32 = 20;
var b: u32 = 10;
std.debug.print("a = {} b = {}\n", .{ a, b });
a, b = if (a > b) .{ b, a } else .{ a, b }; // FIXME this doesn't work, assign to new/other variables
std.debug.print("a = {} b = {}\n", .{ a, b });
}
Output:
a = 20 b = 10
a = 10 b = 10
So technically this isn’t a variable swap but declaring two new variables which may be initialized in a swapped way, despite these caveats — used carefully, it is a good solution.