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

Rust所有权限制问题:已移动值复用的内存友好解决方案

问题描述

编译时遇到以下所有权错误:

error[E0382]: use of moved value: `updated_setting_values`
  --> swu3\src\data_processor\mod.rs:53:9
   |
37 |         let updated_setting_values = data_management(
   |             ----------------------- move occurs because `updated_setting_values` has type `Vec<interfaces::inputs::constants::constants::SettingValues>`, which does not implement the `Copy` trait
...
52 |         self.all_setting_values_in_memory = updated_setting_values;
   |                                            ----------------------- value moved here
53 |         updated_setting_values
   |         ^^^^^^^^^^^^^^^^^^^^^^ value used here after move

相关代码如下:

pub struct DataProcessor {
    count_iterations: u8,
    all_setting_values_in_memory: Vec<SettingValues>,
}

impl DataProcessor {
    pub fn new() -> Self {
        Self {
            count_iterations: 0,
            all_setting_values_in_memory: vec![SettingValues::new()],
        }
    }

    pub fn process_step(
        &mut self,
        default_settings: &[DefaultSetting],
        mode_specific_values: &Vec<SettingValue>,
        current_mode: Mode,
        current_profile: ProfileId,
        reset_mode_flag: bool,
        profile_update_status: ProfileUpdate,
        stored_setting_values: &Vec<SettingValues>,
    ) -> Vec<SettingValues> {
        let is_initial_run = self.count_iterations < 3;

        let selected_values = if INTERNAL_MEMORY_SWITCH {
            &self.all_setting_values_in_memory
        } else {
            stored_setting_values
        };

        let updated_setting_values = data_management(
            default_settings,
            selected_values,
            mode_specific_values,
            current_mode,
            current_profile,
            is_initial_run,
            reset_mode_flag,
            profile_update_status
        );

        if self.count_iterations <= 3 {
            self.count_iterations += 1;
        }

        self.all_setting_values_in_memory = updated_setting_values;
        updated_setting_values
    }
}

需求:self.all_setting_values_in_memory需要持有data_management的输出值,同时process_step要返回该值,且因内存限制不能使用clone方法。

解决方案

方案1:使用共享所有权(推荐,无数据复制)

将all_setting_values_in_memory的类型改为Rc<Vec<SettingValues>>,通过克隆Rc指针共享所有权,底层数据不会被复制,内存开销极小:

use std::rc::Rc;

pub struct DataProcessor {
    count_iterations: u8,
    all_setting_values_in_memory: Rc<Vec<SettingValues>>,
}

impl DataProcessor {
    pub fn new() -> Self {
        Self {
            count_iterations: 0,
            all_setting_values_in_memory: Rc::new(vec![SettingValues::new()]),
        }
    }

    pub fn process_step(
        &mut self,
        default_settings: &[DefaultSetting],
        mode_specific_values: &Vec<SettingValue>,
        current_mode: Mode,
        current_profile: ProfileId,
        reset_mode_flag: bool,
        profile_update_status: ProfileUpdate,
        stored_setting_values: &Vec<SettingValues>,
    ) -> Rc<Vec<SettingValues>> {
        let is_initial_run = self.count_iterations < 3;

        let selected_values = if INTERNAL_MEMORY_SWITCH {
            &self.all_setting_values_in_memory
        } else {
            stored_setting_values
        };

        // 将data_management的结果包裹在Rc中
        let updated_setting_values = Rc::new(data_management(
            default_settings,
            selected_values,
            mode_specific_values,
            current_mode,
            current_profile,
            is_initial_run,
            reset_mode_flag,
            profile_update_status
        ));

        if self.count_iterations <= 3 {
            self.count_iterations += 1;
        }

        // 克隆Rc指针(仅复制指针和引用计数,不复制数据)
        self.all_setting_values_in_memory = updated_setting_values.clone();
        updated_setting_values
    }
}

方案2:返回内部引用(无需额外内存开销)

如果调用者不需要获取值的所有权,可修改函数返回类型为&Vec<SettingValues>,通过生命周期标注保证引用有效性:

pub fn process_step(
    &mut self,
    default_settings: &[DefaultSetting],
    mode_specific_values: &Vec<SettingValue>,
    current_mode: Mode,
    current_profile: ProfileId,
    reset_mode_flag: bool,
    profile_update_status: ProfileUpdate,
    stored_setting_values: &Vec<SettingValues>,
) -> &Vec<SettingValues> {
    let is_initial_run = self.count_iterations < 3;

    let selected_values = if INTERNAL_MEMORY_SWITCH {
        &self.all_setting_values_in_memory
    } else {
        stored_setting_values
    };

    let updated_setting_values = data_management(
        default_settings,
        selected_values,
        mode_specific_values,
        current_mode,
        current_profile,
        is_initial_run,
        reset_mode_flag,
        profile_update_status
    );

    if self.count_iterations <= 3 {
        self.count_iterations += 1;
    }

    self.all_setting_values_in_memory = updated_setting_values;
    // 返回self内部存储的引用
    &self.all_setting_values_in_memory
}

内容的提问来源于stack exchange,提问作者Js7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 14:39:50