Return value if in range else default?

Is there a shorter version of

let range = std::ops::RangeInclusive<u8> = 1..=100;
let value_raw = 200;
let vaue_within_range = if range.contains(&value_raw) { value_raw } else { 1 };
//Assume value is safely within the intended range from this point onwards

Similar to .unwrap_or() and .unwrap_or_default()?

I feel like if range.contains(&value_raw) { value_raw } else { 1 } is already pretty short. If you need this a lot, make your own function :wink:

If you wanted to take either the minimum or the maximum as default, depending on whether the value lies below or above the range, using Ord::clamp would be an option.

4 Likes

Totally missed the existence of clamp :grin:. Is there something similar that takes a range as the min/max bounds? Or I guess I could just use value.clamp(range.min(), range.max()).

No, it was decided to stick with the two parameters, because it's always inclusive, and passing a 1..=10 would imply that 1..10 would work too, but that's a whole other complication. (See comments like https://github.com/rust-lang/rfcs/pull/1961#issuecomment-302600351 .)

Passing the min and the max is the way to go.

1 Like

Clamping to a (half-)open range doesn't make sense when the underlying type is "continuous" (=floating point, for the lack of a better representation). A continuous (half-)open range lacks a minimum and/or a maximum, so when the value is <= infimum or >= supremum, there's no value inside the range to return.

One could use the infimum and the supremum instead, but the returned value not being contained in the range is very confusing. Alternatively, the operation could be defined for discrete types only, but that's 1. surprising in a bad way, and 2. laborious to do generically (it would require something like a new Discrete trait).

1 Like

Because floating-point isn't actually continuous, it would be possible to have PI.clamp(0.0_f32 .. 1.0) => 0.99999994_f32 (0x3F7FFFFF) as that's the largest representable value below one.

But

is very true, and the big reason why std's clamp didn't even try that.

1 Like

Sure thing! However, I'd actually argue that it's conceptually not the right thing to do, even if technically possible. Floats are much more often used as an approximation to real numbers, and not completely accurately as they are, base-2 rational numbers with scientific notation.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.