在循环中构建 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);
}
}
我得到的错误是
mismatched types: expected std::process::Command
, found &mut std::process::Command
查看 std::process::Command::arg
的文档,它说它需要一个 &mut self
和 returns 一个 &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
调用的 return 值 有问题。让我们看看 documentation for arg
:
fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command
因此,arg
对 self
的可变引用进行操作,接受 arg
参数,并且 returns对自身的可变引用。让我们稍微更改您的代码以检验我们的假设。我们将使用一个技巧 make the compiler tell us the types of variables:
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
并按值接受 return。在这种情况下,您 将 必须在每个步骤之间跟踪生成器,并且您的代码将按原样运行。
我是 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);
}
}
我得到的错误是
mismatched types: expected
std::process::Command
, found&mut std::process::Command
查看 std::process::Command::arg
的文档,它说它需要一个 &mut self
和 returns 一个 &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
调用的 return 值 有问题。让我们看看 documentation for arg
:
fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command
因此,arg
对 self
的可变引用进行操作,接受 arg
参数,并且 returns对自身的可变引用。让我们稍微更改您的代码以检验我们的假设。我们将使用一个技巧 make the compiler tell us the types of variables:
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
并按值接受 return。在这种情况下,您 将 必须在每个步骤之间跟踪生成器,并且您的代码将按原样运行。