rust - 如何从Rayon的 `par_iter()`引起 panic ?

标签 rust panic rayon

我正在尝试从par_iter()内部捕捉到 panic ,并继续执行par_iter块之后的操作。

如果我有这个,我会正确地获得一切,并且不会出现 panic :

let dog: Dog = Dog {
    name: "Dog",
    vector: vec![1, 2, 3, 4, 5],
};
let cat: Cat = Cat {
    name: "Cat",
    vector: vec![1, 2, 3],
};
let pig: Pig = Pig {
    name: "Pig",
    vector: vec![1, 2, 3, 4, 5],
};
let mut v: Vec<Box<dyn Animal>> = Vec::new();
v.push(Box::new(cat));
v.push(Box::new(dog));
v.push(Box::new(pig));

let total = v
    .par_iter()
    .map(|x| {
        println!("{} vector[1] is {:?}", &x.name(), &x.vector()[1]);
        x.vector()[1].clone()
    })
    .collect::<Vec<(i32)>>();

let sum: i32 = total.iter().sum();
println!("sum: {}", sum);

我得到par_iter之后的总和

Cat vector[1] is 2
Dog vector[1] is 2
Pig vector[1] is 2
sum: 6

当我尝试访问超出向量长度的索引时,我仍然会打印出包括 panic 在内的所有内容,但不要进入sum:
let total = v
    .par_iter()
    .map(|x| {
        println!("{} vector[4] is {:?}", &x.name(), &x.vector()[4]);
        x.vector()[4].clone()
    })
    .collect::<Vec<(i32)>>();

let sum: i32 = total.iter().sum();
println!("sum: {}", sum);

结果:

     Running `target/debug/playground`
thread '<unnamed>' panicked at 'index out of bounds: the len is 3 but the index is 4', /rustc/4560ea788cb760f0a34127156c78e2552949f734/src/libcore/slice/mod.rs:2717:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Standard Output
Dog vector[4] is 5
Pig vector[4] is 5

我尝试检查如果实现了panic_handler怎么办:
let panic_handler = move |err: Box<dyn Any + Send>| {
    println!("hello");
};
rayon::ThreadPoolBuilder::new()
    .num_threads(2)
    .panic_handler(panic_handler)
    .build_global()
    .unwrap();

它不起作用,甚至没有被使用:

warning: unused variable: `err`
  --> src/main.rs:52:31
   |
52 |     let panic_handler = move |err: Box<dyn Any + Send>| {
   |                               ^^^ help: consider prefixing with an underscore: `_err`

playground

我真正的问题不是关于向量的界限,而是关于如果我不知道它是否会发生 panic ,请从par_iter中捕获 panic 。我的目标是收集结果并继续前进,不要 panic 。

最佳答案

尝试使用get(如果索引4处有一个元素,则返回Some(element),否则返回None):

let total = v.par_iter().map(|x| {
    println!("{} vector[4] is {:?}", &x.name(), &x.vector().get(4));
    x.vector().get(4).map(|x| x.clone())
}).collect::<Vec<Option<i32>>>();

然后,total将包含存在相应元素的Some(n),否则包含None

关于rust - 如何从Rayon的 `par_iter()`引起 panic ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59091329/

相关文章:

logging - 在 golang 中捕获 panic()

memory-management - 用Rust中的人造丝和Indicatif进行内存泄漏

rust - 如何更改功能以与Rayon并行运行?

unit-testing - 应该如何组织 Rust 单元测试?

unicode - 如何检测非规范化的 unicode 字符?

rust - 如何通过副作用实现变量增量?

c - 是否可以使用C从Rust内置的静态库中调用函数?

linux - 使用 Coda 访问服务器 SSH/sFTP

rust - 为什么打开克隆的 Rc 会引起 panic ?