如何测试一个值是否在范围内?

38

我希望能够创建一个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_check), 为这个箱子提供了 ContainsWithin 特性。 - Ben S
7个回答

61

从Rust 1.35开始,原始代码将 几乎1 可以使用Range::contains直接编译:

fn main() {
    let a = 3..5;
    assert!(a.contains(&4));
}

1&4而不是4传递给contains()函数。


4
是否有一个名为between(a,b)的方法,可以在任何数字类型上调用,这不是很合理吗?我喜欢你的答案,但我不确定是否喜欢需要先创建“Range”的方式。原因非常简单:大多数IDE将自动完成“between”方法。 - Boss Man

11
您也可以使用match
fn main() {
    let v = 132;
    match v {
        1...100 => println!("Inside"),
        _ => println!("Outside")
    }
}

2
根据rustc 1.51.0版本,区间模式(range pattern)已经被弃用,请使用..=(包含范围)代替。另请参阅独占范围模式的跟踪问题 - Robert Jaskowski

9

Range本身没有任何内容(目前还没有),但是这并不难做到;毕竟,它只需要进行一些比较:

4 >= a.start && 4 < a.end

你认为增加这个功能(到所有的“Range*”结构体中)的PR会受到欢迎吗? - Shepmaster
2
不经过RFC是不行的。坦白地说,在1.0版本之前,非必要的功能扩展是不太可能的。话虽如此,编写RFC相对容易。 - bluss
负数怎么办? - mkirk
@mkirk:负数怎么办?如果你使用有符号整数,负数并没有什么特别之处。 - Chris Morgan

8

您还可以使用if let,它与match类似:

if let 3..=5 = 4 {
    println!("Inside");
}

同时将其分配给变量也非常容易:

let s = if let 3..=5 = 4 {
    "Inside"
} else {
    "Outside"
};
println!("{}", s);

请注意,这仅适用于const范围。 - L. F.

0

你可以使用我的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");
}

它还有其他范围比较方法,用于左右限制等。


0

这并不是严格回答你的问题,但如果你想测试一个变量是否在另外两个变量之间,你可以使用 chain-cmp crate:

use chain_cmp::chmp;

let n = 7;
assert!(chmp!(5 <= n < 10));

chmp!相比独立的between函数的好处在于,您自然可以看到范围的结尾是包含还是排除在外。


-1

在进入问题之前,你可以通过以下方式使你的代码更加漂亮。

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的所有权和借用系统,在使用某些函数时,您应始终考虑使用带有引用的文字而不仅仅将值放入函数的参数中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接