相关疑难解决方法(0)

为什么我不能在同一个结构中存储值和对该值的引用?

我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:

struct Thing {
    count: u32,
}

struct Combined<'a>(Thing, &'a u32);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing { count: 42 };

    Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)

有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:

struct Combined<'a>(Thing, &'a Thing);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing::new();

    Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)

有时,我甚至没有参考该值,我得到同样的错误:

struct Combined<'a>(Parent, Child<'a>);

fn make_combined<'a>() -> Combined<'a> {
    let parent = Parent::new();
    let child = parent.child();

    Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)

在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?

lifetime rust borrow-checker

193
推荐指数
3
解决办法
2万
查看次数

如何返回对互斥锁下的值的子值的引用?

我有一个看起来像这样的结构:

pub struct MyStruct {
    data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
Run Code Online (Sandbox Code Playgroud)

我可以很容易地锁定互斥锁并查询底层HashMap:

let d = s.data.lock().unwrap();
let v = d.get(&1).unwrap();
println!("{:?}", v);
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个封装查询的方法,所以我写了这样的东西:

impl MyStruct {
    pub fn get_data_for(&self, i: &i32) -> &Vec<i32> {
        let d = self.data.lock().unwrap();
        d.get(i).unwrap()
    }
}
Run Code Online (Sandbox Code Playgroud)

这无法编译,因为我试图在以下情况下返回对数据的引用Mutex:

error: `d` does not live long enough
  --> <anon>:30:9
   |
30 |         d.get(i).unwrap()
   |         ^
   |
note: reference must be valid for the anonymous lifetime #1 defined on the block at 28:53...
  --> <anon>:28:54
   |
28 …
Run Code Online (Sandbox Code Playgroud)

rust

15
推荐指数
4
解决办法
1493
查看次数

可变借用互斥体内部的对象 - 如何重构?

我的许多功能中都有以下模式:

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

struct State { 
    value: i32
}

fn foo(data: Arc<Mutex<State>>) {
    let state = &mut data.lock().expect("Could not lock mutex");
    // mutate `state`
}
Run Code Online (Sandbox Code Playgroud)

&mut *data.lock().expect("Could not lock mutex") 一遍又一遍地重复,所以我想将它重构为一个函数,以便编写类似

let state = get_state(data); 
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法:

fn get_state(data: &Arc<Mutex<State>>) -> &mut State {
    &mut data.lock().expect("Could not lock mutex")
}
Run Code Online (Sandbox Code Playgroud)

哪个无法编译:

错误:无法返回引用临时值的值

这让我相信data.state.lock().expect("...")价值回报。但是,我可以看到状态通过在这个 playground 上的多次foo调用而发生变化。

这里发生了什么?为什么我看似简单的重构编译失败?


编辑:

我希望以下内容也能正常工作:

fn get_state<'a>(data: &'a Arc<Mutex<State>>) -> &'a mut State {
    let state: &'a mut State = &mut …
Run Code Online (Sandbox Code Playgroud)

refactoring mutex rust borrowing

2
推荐指数
2
解决办法
988
查看次数

标签 统计

rust ×3

borrow-checker ×1

borrowing ×1

lifetime ×1

mutex ×1

refactoring ×1