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

huangapple go评论66阅读模式
英文:

cannot move out of `keymap.command` which is behind a shared reference

问题

以下是用于运行终端命令的模拟代码:

#[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!("使用键映射执行某些操作:{:?}", keymap);

    run_command(&keymap.command);
}

fn run_command(command_string: &str) {
    let command_string = command_string.replace("test", "best");

    println!("运行此命令:{:?}", command_string);
}

fn main() {
    let keymap = vec![Keymap::new('t', "echo 'test'")].into_iter().next().unwrap();

    handle_keymap(&keymap);
}

现在,这个代码不再使用 clone(),而是通过将 run_command 函数修改为接受 &str 参数来避免移动 keymap.command。这是一种更好的做法,因为它避免了不必要的内存分配和拷贝。

英文:

The following is a mock code for running a terminal command:

#[derive(Debug)]
pub struct Keymap {
    pub key: char,
    pub command: String,
}

impl Keymap {
    pub fn new&lt;S: AsRef&lt;str&gt;&gt;(key: char, command: S) -&gt; Self {
        let command = command.as_ref().to_owned();

        Self {
            key,
            command,
        }
    }
}

fn handle_keymap(keymap: &amp;Keymap) {
    println!(&quot;Do something with the keymap: {:?}&quot;, keymap);

    run_command(keymap.command);
}

fn run_command(command_string: String) {
    let command_string = command_string.replace(&quot;test&quot;, &quot;best&quot;);

    println!(&quot;Running this command: {:?}&quot;, command_string);
}

fn main() {
    let keymap = vec![Keymap::new(&#39;t&#39;, &quot;echo &#39;test&#39;&quot;)].into_iter().next().unwrap();

    handle_keymap(&amp;keymap);
}

Rust Playground

Right now, there's an error here:

error[E0507]: cannot move out of `keymap.command` which is behind a shared reference
  --&gt; 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

Which can be solved by using clone():

run_command(keymap.command.clone());

Is there another solution? I think using clone() like this isn't good practice?

答案1

得分: 1

函数run_command 拥有 传递的 String 参数的所有权。但它无法这样做,因为 keymap.command 在一个共享引用后面。根据您想要做什么,您应该执行以下其中之一:

  1. 如果您想要 run_command 更改传递的命令,但不要为调用者反映这一更改,您应该保留 run_command 如现在所示,并确实在 keymap.command 上调用 clone()。您可以将 &amp;String(或 &amp;str)传递给 run_command 并在内部克隆它,但最好将该决策留给调用者

  2. 如果您想要 run_command 更改实际的 keymap.command,请传递一个 &amp;mut String。这还将强迫您更改 handle_keymap,以接受 &amp;mut Keymap 而不是 &amp;Keymap

  3. 如果您不想在 run_command 内部更改命令,那么不要这样做,并将其更改为通过引用获取字符串 &amp;String(或者更好地利用 deref coercion 并将 command 传递为 &amp;str)。

如果您想要不同的东西,您将需要在您的问题中更具体,以便我们帮助您。

英文:

Function run_command takes an ownership of passed String argument. But it cannot do that, since keymap.command is behind a shared reference. Depending on what you are trying to do you should do one of the following:

  1. If you want run_command to change passed command, but not reflect that for the caller you should leave run_command as it is now and indeed call clone() on keymap.command. You could pass &amp;String (or &amp;str) to run_command and clone it inside, but it is better to leave that decision to the caller.

  2. If you want run_command to change actual keymap.command pass it a &amp;mut String instead. This will also force you to change handle_keymap to take &amp;mut Keymap instead of &amp;Keymap.

  3. If you don't want to mutate command inside run_command then don't do it and change it to take string by reference &amp;String (or event better take advantage of deref coercion and pass command as &amp;str).

If you want something different, you will have to be more specific in your question for us to help you.

huangapple
  • 本文由 发表于 2023年7月13日 16:46:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677508.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定