Reputation: 430991
I'd like to be able to create a Range
and then test if a variable is contained in that range. Something that looks like this:
fn main() {
let a = 3..5;
assert!(a.contains(4));
}
Right now, the only obvious thing I see is to use Iterator::any
. This is ugly because it would take an O(1) operation and make it O(n):
fn main() {
let mut a = 3..5;
assert!(a.any(|v: i32| v == 4));
}
Upvotes: 46
Views: 42402
Reputation: 49
Before getting into question, you can manifest your code fancier a bit in this way.
fn main() {
assert!((3..5).contains(&4));
}
Parentheses around 3..5 must used because 3..5.contains($4)
is same as 3..(5.contains($4))
.
Let's start with why we need &
before 4
in contains()
method.
contains()
method take reference as parameter. You can find It in rust reference -- contains()
method in Range
struct.
What that means is you are not taking ownership from the parameter of contains()
. This method is used to check whether there is the item you are looking for, or not. Therefore, there is no reason for this method should take ownership of the item which is the parameter of contains()
.
This is why you got compile error and this might be confused at first. Due to ownership and borrowing system of rust, when you are using some functions, you should always consider using literal with reference rather than just put value into the parameter of functions.
Upvotes: -1
Reputation: 349
You can use match
too:
fn main() {
let v = 132;
match v {
1..=100 => println!("Inside"),
_ => println!("Outside")
}
}
Upvotes: 14
Reputation: 1818
This doesn't technically answer your question, but if you want to test that a variable is between two other variables, you could use chain-cmp
crate:
use chain_cmp::chmp;
let n = 7;
assert!(chmp!(5 <= n < 10));
The nice thing about chmp!
compared to a stand-alone between
function is that you naturally see whether range ends are included or excluded.
Upvotes: 1
Reputation: 186
You can use my crate cond_utils which allows you to write things like:
if number.between(0, 10) {
println!("Number is between 0 and 10, limits excluded");
}
or:
if number.within(0, 10) {
println!("Number is between 0 and 10, limits included");
}
It also has other range comparison methods, for left and right limits, etc.
Upvotes: 0
Reputation: 2835
You can also use if let
, which is similar to match
:
if let 3..=5 = 4 {
println!("Inside");
}
Also it is easy to assign to a variable:
let s = if let 3..=5 = 4 {
"Inside"
} else {
"Outside"
};
println!("{}", s);
Upvotes: 13
Reputation: 430991
As of Rust 1.35, the original code will almost1 compile as-is using Range::contains
:
fn main() {
let a = 3..5;
assert!(a.contains(&4));
}
1 Passing &4
instead of 4
to contains()
.
Upvotes: 75
Reputation: 90782
There is nothing on Range
itself (at present, anyway), but it is not difficult to do this; after all, it just takes a couple of comparisons:
4 >= a.start && 4 < a.end
Upvotes: 10