You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:25:31