下面是运行终端命令的模拟代码:
#[derive(Debug)]
pub struct Keymap {
pub key: char,
pub command: String,
}
impl Keymap {
pub fn new<S: AsRef<str>>(key: char, command: S) -> Self {
let command = command.as_ref().to_owned();
Self {
key,
command,
}
}
}
fn handle_keymap(keymap: &Keymap) {
println!("Do something with the keymap: {:?}", keymap);
run_command(keymap.command);
}
fn run_command(command_string: String) {
let command_string = command_string.replace("test", "best");
println!("Running this command: {:?}", command_string);
}
fn main() {
let keymap = vec![Keymap::new('t', "echo 'test'")].into_iter().next().unwrap();
handle_keymap(&keymap);
}
字符串
Rust Playground
现在,这里有一个错误:
error[E0507]: cannot move out of `keymap.command` which is behind a shared reference
--> src/main.rs:21:17
|
21 | run_command(keymap.command);
| ^^^^^^^^^^^^^^ move occurs because `keymap.command` has type `String`, which does not implement the `Copy` trait
型
可以用clone()
来解决:
run_command(keymap.command.clone());
型
有别的解决办法吗?我认为像这样使用clone()
不是一个好的做法。
1条答案
按热度按时间68bkxrlz1#
函数
run_command
获取传入的String
参数的所有权。但它不能这样做,因为keymap.command
位于共享引用后面。根据您尝试执行的操作,您应该执行以下操作之一:1.如果你想让
run_command
改变传递的命令,但不反映调用者的情况,你应该让run_command
保持原样,并在keymap.command
上调用clone()
。您可以将&String
(或&str
)传递给run_command
并在内部克隆它,但最好将此决定留给调用者。1.如果你想让
run_command
改变实际的keymap.command
,则传递一个&mut String
。这也将迫使您将handle_keymap
更改为&mut Keymap
而不是&Keymap
。1.如果你不想在
run_command
内部改变命令,那就不要这样做,把它改为引用字符串&String
(或者事件最好利用deref强制转换,把command
作为&str
传递)。如果你想要不同的东西,你必须在你的问题更具体,我们可以帮助你。