我希望能够创建一个Range
,并测试变量是否包含在该范围内。类似于这样:
fn main() {
let a = 3..5;
assert!(a.contains(4));
}
目前,我唯一明显的想法是使用Iterator::any
。这样做很丑陋,因为它会将一个O(1)的操作变成一个O(n)的操作:
fn main() {
let mut a = 3..5;
assert!(a.any(|v: i32| v == 4));
}
我希望能够创建一个Range
,并测试变量是否包含在该范围内。类似于这样:
fn main() {
let a = 3..5;
assert!(a.contains(4));
}
目前,我唯一明显的想法是使用Iterator::any
。这样做很丑陋,因为它会将一个O(1)的操作变成一个O(n)的操作:
fn main() {
let mut a = 3..5;
assert!(a.any(|v: i32| v == 4));
}
从Rust 1.35开始,原始代码将 几乎1 可以使用Range::contains
直接编译:
fn main() {
let a = 3..5;
assert!(a.contains(&4));
}
1将&4
而不是4
传递给contains()
函数。
between(a,b)
的方法,可以在任何数字类型上调用,这不是很合理吗?我喜欢你的答案,但我不确定是否喜欢需要先创建“Range”的方式。原因非常简单:大多数IDE将自动完成“between”方法。 - Boss Manmatch
:fn main() {
let v = 132;
match v {
1...100 => println!("Inside"),
_ => println!("Outside")
}
}
Range
本身没有任何内容(目前还没有),但是这并不难做到;毕竟,它只需要进行一些比较:
4 >= a.start && 4 < a.end
您还可以使用if let
,它与match
类似:
if let 3..=5 = 4 {
println!("Inside");
}
同时将其分配给变量也非常容易:
let s = if let 3..=5 = 4 {
"Inside"
} else {
"Outside"
};
println!("{}", s);
你可以使用我的crate cond_utils,它允许你编写类似以下的代码:
if number.between(0, 10) {
println!("Number is between 0 and 10, limits excluded");
}
或者:
if number.within(0, 10) {
println!("Number is between 0 and 10, limits included");
}
它还有其他范围比较方法,用于左右限制等。
这并不是严格回答你的问题,但如果你想测试一个变量是否在另外两个变量之间,你可以使用 chain-cmp
crate:
use chain_cmp::chmp;
let n = 7;
assert!(chmp!(5 <= n < 10));
chmp!
相比独立的between
函数的好处在于,您自然可以看到范围的结尾是包含还是排除在外。
在进入问题之前,你可以通过以下方式使你的代码更加漂亮。
fn main() {
assert!((3..5).contains(&4));
}
在3..5周围必须使用括号必须,因为3..5.contains($4)
与3..(5.contains($4))
相同。
让我们从为什么需要在contains()
方法之前加上$
来开始。
contains()
方法以引用作为参数。您可以在Rust参考中找到它--Range
结构中的contains()
方法。
这意味着您不会从contains()
的参数中获取所有权。此方法用于检查是否存在您要查找的项目。因此,该方法不应获取contains()
的参数的所有权。
这就是为什么您会得到编译错误并且可能会感到困惑的原因。由于Rust的所有权和借用系统,在使用某些函数时,您应始终考虑使用带有引用的文字而不仅仅将值放入函数的参数中。
range_check
), 为这个箱子提供了Contains
和Within
特性。 - Ben S