繁体   English   中英

在循环中构建std :: process :: Command时类型不匹配

[英]Mismatched types when building a std::process::Command in a loop

我是Rust的新手,试图通过借用检查器来学习安全编程。 我尝试过的一件事是根据输入构造一个std::process::Command

如果我只是想做文档中的所有示例假设我想做的事情,并且只运行一个带有我在编码时知道的参数的命令,它就可以正常工作:

use std::process::Command;

fn main() {
    let mut command = Command::new("/usr/bin/x-terminal-emulator")
                              .arg("-e")
                              .arg("editor")
                              .output()
                              .unwrap();
}

我正在尝试运行我在运行时构建的命令。 为了做到这一点,我需要将Command结构的构造与其参数的构建分开。 当我这样做时,编译器抱怨不匹配的类型:

use std::env::args;
use std::process::Command;

fn main() {
    let args = args().collect::<Vec<_>>();
    let mut command = Command::new("/usr/bin/x-terminal-emulator");

    for arg in &args[1..args.len()] {
        command = command.arg(arg);
    }
}

我得到的错误是

不匹配的类型:期望的std::process::Command ,found &mut std::process::Command

查看std::process::Command::arg的文档,它说它需要一个&mut self并返回一个&mut Command 据编译器说,这正是它所得到的。 文档是错误的,还是(更有可能)我在这里误解了什么?

如果我们检查编译器提供的完整错误,这可能有助于解决问题:

error: mismatched types:
 expected `std::process::Command`,
    found `&mut std::process::Command`
(expected struct `std::process::Command`,
    found &-ptr) [E0308]

command = command.arg(arg);
          ^~~~~~~~~~~~~~~~

编译器指向表达式的整个右侧。 这表明arg调用的返回值有问题。 我们来看看arg文档

fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command

因此, argself进行可变引用,接受arg参数,并返回对自身的可变引用。 让我们改变你的代码来测试我们的假设。 我们将使用一个技巧让编译器告诉我们变量的类型

for arg in &args[1..args.len()] {
    let _: () = command;
    let _: () = command.arg(arg);
}

这会产生错误:

error: mismatched types:
 expected `()`,
    found `std::process::Command`

let _: () = command;
            ^~~~~~~

error: mismatched types:
 expected `()`,
    found `&mut std::process::Command`

let _: () = command.arg(arg);
            ^~~~~~~~~~~~~~~~

哈,我们明白了! 我们正尝试将存储&mut Command为类型的变量Command 不会工作! 由于构建器模式的这个实例会改变构建器,因此我们不必执行任何特殊操作来保留它:

use std::env;
use std::process::Command;

fn main() {
    let mut command = Command::new("/usr/bin/x-terminal-emulator");

    for arg in env::args().skip(1) {
        command.arg(arg);
    }
}

还有另一种构建器模式样式,它按值接受self并按值返回它。 在这种情况下,你必须跟踪每个步骤之间的建设者,和你的代码会工作原样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM