rust 意外结果RangeInclusive< >::all()

2ledvvac  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(89)

我得到了一个以下的部分生 rust 的代码,期望检查'range_a:RangeInclusive<>'包括'range_B:RangeInclusive<>',反之亦然。我不知道它是如何工作的,在某些情况下返回错误的结果。有人能解释一下吗?

fn contains_range(mut range_a: RangeInclusive<u32>, mut range_b: RangeInclusive<u32>) -> bool {
    range_b.all(|i| range_a.contains(&i)) || range_a.all(|i| range_b.contains(&i))
}

fn main() {
     dbg!(contains_range(15..=16, 15..=73));
}

字符串
我猜问题是RangeInclusive<>::all(),但如果是的话,那么编译器应该在RangeInclusive<>::contains()处有警告。

ddhy6vgd

ddhy6vgd1#

如果你把dbg调用分散到所有地方,你会注意到调用range_b.all推进了range_b,所以当你到达第二个测试时,range_b已经变成了18..=73

use std::ops::RangeInclusive;

fn contains_range(mut range_a: RangeInclusive<u32>, mut range_b: RangeInclusive<u32>) -> bool {
    range_b.all(|i| range_a.contains(&i)) || range_a.all(|i| dbg!(dbg!(&range_b).contains(&dbg!(i))))
}

fn main() {
     dbg!(contains_range(15..=16, 15..=73));
}

字符串
Playground
给出:

[src/main.rs:4] &range_b = 18..=73
[src/main.rs:4] i = 15
[src/main.rs:4] dbg!(& range_b).contains(&dbg!(i)) = false
[src/main.rs:8] contains_range(15..=16, 15..=73) = false


解决方案是在调用all之前克隆范围:

use std::ops::RangeInclusive;

fn contains_range(range_a: RangeInclusive<u32>, range_b: RangeInclusive<u32>) -> bool {
    range_b.clone().all(|i| range_a.contains(&i)) || range_a.clone().all(|i| range_b.contains(&i))
}

fn main() {
     dbg!(contains_range(15..=16, 15..=73));
}


Playground

相关问题