Rust中`keymap.command`移出共享引用报错,除clone外还有其他解法吗?
替代
clone()解决Rust所有权错误的方案 原代码中handle_keymap接收&Keymap引用,尝试将keymap.command(String类型)传递给run_command时触发所有权移动错误,因为String未实现Copy trait。除了clone(),还有以下更优方案:
方案1:将run_command的参数改为&str(最优解)
因为run_command内部仅对字符串做替换操作,不需要拥有字符串的所有权。str::replace方法可直接接收&str参数并返回新的String,完全无需复制原字符串的所有权。
修改后的代码:
#[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); } // 参数改为&str,无需所有权 fn run_command(command_string: &str) { 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); }
方案2:让handle_keymap接收Keymap所有权而非引用
如果业务场景中不需要保留原Keymap实例,可以修改handle_keymap的参数类型为Keymap,直接转移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, } } } // 参数改为Keymap,获取所有权 fn handle_keymap(keymap: Keymap) { println!("Do something with the keymap: {:?}", keymap); // 直接转移command的所有权 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); }
方案3:使用Cow<str>实现灵活的所有权处理
如果run_command有时需要修改字符串、有时不需要,可以使用std::borrow::Cow(Clone-On-Write)避免不必要的复制——仅当需要修改时才克隆原字符串,否则直接使用引用。
修改后的代码:
use std::borrow::Cow; #[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); // 传递Cow::Borrowed引用 run_command(Cow::Borrowed(&keymap.command)); } fn run_command(mut command_string: Cow<str>) { // 仅当需要修改时才克隆原字符串 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); }
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

