微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Rust 的 `run_cmd`

如何解决使用 Rust 的 `run_cmd`

只是一个快速的免责声明,让您知道我是一个完整的 Rust 文盲。把这个排除在外,我可以转向问题。

我正在尝试使用 Rust 的 globrun_cmd 返回的迭代器上运行 Python 脚本。换句话说,我正在尝试运行一个 Python 脚本,该脚本将文件名和整数作为命令行输入,并且我希望仅在具有特定扩展名的文件上运行此脚本。

为了获取带有我想要的扩展名的文件,我使用 Rust 的 glob crate 返回一个带有这些文件路径的迭代器。有了这个迭代器,我正在尝试运行以下代码将它们传递给 Python 脚本:

use cmd_lib::*;
use rayon::prelude::*;
use glob::glob;

fn main() {
    glob("../split_parsed/*.output")
        .into_par_iter()
        .for_each(|pattern|{
            run_cmd!(./src/aggregate.py ${pattern} 500).unwrap();
        });
}

运行这个我得到以下错误

error[E0599]: the method `to_string` exists for struct `Paths`,but its trait bounds were not satisfied
  --> src/main.rs:9:13
   |
9  |             run_cmd!(./src/aggregate.py ${pattern} 500).unwrap();
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Paths` due to unsatisfied trait bounds
   | 
  ::: /home/ducbueno/.cargo/registry/src/github.com-1ecc6299db9ec823/glob-0.3.0/src/lib.rs:88:1
   |
88 | pub struct Paths {
   | ----------------
   | |
   | doesn't satisfy `Paths: ToString`
   | doesn't satisfy `Paths: std::fmt::display`
   |
   = note: the following trait bounds were not satisfied:
           `Paths: std::fmt::display`
           which is required by `Paths: ToString`
   = note: this error originates in a macro (in Nightly builds,run with -Z macro-backtrace for more info)

error: aborting due to prevIoUs error

For more information about this error,try `rustc --explain E0599`.
error: Could not compile `aggregate`

Caused by:
  process didn't exit successfully: `rustc --crate-name aggregate --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C Metadata=d0ac83c95bbb3012 -C extra-filename=-d0ac83c95bbb3012 --out-dir /hdd/mysrc/parse_gem5_debug/aggregate/target/debug/deps -C incremental=/hdd/mysrc/parse_gem5_debug/aggregate/target/debug/incremental -L dependency=/hdd/mysrc/parse_gem5_debug/aggregate/target/debug/deps --extern cmd_lib=/hdd/mysrc/parse_gem5_debug/aggregate/target/debug/deps/libcmd_lib-db4ce11b465defbd.rlib --extern glob=/hdd/mysrc/parse_gem5_debug/aggregate/target/debug/deps/libglob-99b91896bb92b644.rlib --extern rayon=/hdd/mysrc/parse_gem5_debug/aggregate/target/debug/deps/librayon-a4ecce8f6a92d238.rlib` (exit code: 1)

有谁知道我该如何解决这个问题?也非常欢迎任何建议。

谢谢!

PS - 另一个快速免责声明:我想使用 Rust 来执行此任务,因为可以与 Rayon 并行运行文件中的 Python 脚本。我在过去使用 Rayon 过去提供的并行功能时有很好的经验,我想再次使用它。

编辑 - 完整的错误信息。

解决方法

我建议通读 Rust Book 的 Error Handling 章节,尤其是涉及 Result 的部分。

函数调用 glob("../split_parsed/*.output") 可能会失败(大概是由于 I/O 原因)并因此返回 Result。您在这里被 .into_par_iter() 愚弄了,因为 Result is 也是一个迭代器(如果成功,它会产生一个元素,否则不会产生)。因此,您在 .for_each() 中得到的是完整的 Paths 对象,这不是您想要的。

这是一个工作示例:

fn main() {
    glob("../split_parsed/*.output")
        .expect("globbing failed")
        .map(|path| path.expect("globbing failed"))
        .par_bridge()
        .for_each(|path| {
            run_cmd!(./src/aggregate.py ${path} 500).unwrap();
        });
}

如果初始通配或后续查询失败,我在这里使用 .expect() 使程序崩溃。然后使用 .par_bridge() 而不是 .into_par_iter() 因为 Paths 没有实现它。希望这对你有用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。