英文:
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<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);
}
Right now, there's an error here:
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
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
在一个共享引用后面。根据您想要做什么,您应该执行以下其中之一:
-
如果您想要
run_command
更改传递的命令,但不要为调用者反映这一更改,您应该保留run_command
如现在所示,并确实在keymap.command
上调用clone()
。您可以将&String
(或&str
)传递给run_command
并在内部克隆它,但最好将该决策留给调用者。 -
如果您想要
run_command
更改实际的keymap.command
,请传递一个&mut String
。这还将强迫您更改handle_keymap
,以接受&mut Keymap
而不是&Keymap
。 -
如果您不想在
run_command
内部更改命令,那么不要这样做,并将其更改为通过引用获取字符串&String
(或者更好地利用 deref coercion 并将command
传递为&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:
-
If you want
run_command
to change passed command, but not reflect that for the caller you should leaverun_command
as it is now and indeed callclone()
onkeymap.command
. You could pass&String
(or&str
) torun_command
and clone it inside, but it is better to leave that decision to the caller. -
If you want
run_command
to change actualkeymap.command
pass it a&mut String
instead. This will also force you to changehandle_keymap
to take&mut Keymap
instead of&Keymap
. -
If you don't want to mutate command inside
run_command
then don't do it and change it to take string by reference&String
(or event better take advantage of deref coercion and passcommand
as&str
).
If you want something different, you will have to be more specific in your question for us to help you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论