从 clone() 开始,Arc 的生命周期不够长 [英] Arc lifetime does not live long enough from clone()

查看:18
本文介绍了从 clone() 开始,Arc 的生命周期不够长的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个可能在线程之间共享的参数结构.它有一个名为 layer_storage 的成员,一些成员需要对其进行变异.我尝试了以下代码,但收到一条错误消息,指出克隆的 Arc 寿命不够长.在添加 Arc> 之前,同一成员工作正常.

I'm trying to create a parameter structure that will possibly be shared between threads. It has a member called layer_storage which some members will need to mutate. I tried the following code, but am getting an error saying that the cloned Arc does not live long enough. This same member worked fine before the addition of Arc<Mutex<>>.

use std::sync::{Arc, Mutex};

#[derive(Clone)]
pub struct Params {
    pub optional: Vec<f32>,
}

pub struct ParamManager {
    layer_storage: Arc<Mutex<Vec<Params>>>,
}

impl Default for ParamManager {
    fn default() -> ParamManager {
        ParamManager {
            layer_storage: Arc::new(Mutex::new(vec![Params { optional: vec![1.0f32, 2.0f32] },
                                                    Params { optional: vec![3.0f32, 4.0f32] }])),
        }
    }
}

impl ParamManager {
    pub fn get_mut_params(&mut self, layer_index: usize) -> &mut Params {
        let layers_arc = self.layer_storage.clone();
        let layers = layers_arc.get_mut().unwrap();
        // tried this initially:
        // let layers = self.layer_storage.clone().get_mut().unwrap();
        assert!(layers.len() - 1 >= layer_index);
        &mut layers[layer_index]
    }
}

fn main() {
    let mut bla = ParamManager::default();
    let i = bla.get_mut_params(0);
}

(游乐场)

推荐答案

正如@Shepmaster 所说,你不能仅仅从get_mut_params;这是您从他们那里得到的保证之一!

As @Shepmaster says you can't just return a reference to something inside the Arc<Mutex<T>> from the get_mut_params; this is one of the guarantees you get from them!

在可能的情况下有效的一种解决方案是将函数翻过来;而不是返回一个可变引用,取一个给定可变引用的闭包:

One solution which works in may cases is to turn the function inside out; rather than returning a mutable reference, take a closure which is given the mutable reference:

impl ParamManager {
    pub fn with_mut_params<F>(&mut self, layer_index: usize, mut f: F)
                     where F: FnMut(&mut Params) {
        let layers_arc = self.layer_storage.clone();
        let layers = layers_arc.lock().unwrap();
        f(&mut layers[layer_index]);
    }
}

fn main() {
    let mut bla = ParamManager::default();

    // Context used by the closure
    let some_var: i32 = 7;
    let other_var: mut MyContext = do_something();

    bla.with_mut_params(0, |i| {
       // do stuff with i
       ...
       // A closure has access to surrounding variables
       other_var.foo(i, some_var);
    });

}

这篇关于从 clone() 开始,Arc 的生命周期不够长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆