rust 无法移出位于共享引用后面的`keymap.command`

gjmwrych  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(84)

下面是运行终端命令的模拟代码:

#[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()不是一个好的做法。

68bkxrlz

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传递)。
如果你想要不同的东西,你必须在你的问题更具体,我们可以帮助你。

相关问题