首页 > 解决方案 > 如何返回两个借用的 RefCell 的组合?

问题描述

我有一个结构,其中两个Vecs 包裹在RefCells 中。我想在该结构上有一个方法,它结合了两个向量并将它们作为新的RefCell或返回RefMut

use std::cell::{RefCell, RefMut};

struct World {
    positions: RefCell<Vec<Option<Position>>>,
    velocities: RefCell<Vec<Option<Velocity>>>,
}

type Position = i32;
type Velocity = i32;

impl World {
    pub fn new() -> World {
        World {
            positions: RefCell::new(vec![Some(1), None, Some(2)]),
            velocities: RefCell::new(vec![None, None, Some(1)]),
        }
    }

    pub fn get_pos_vel(&self) -> RefMut<Vec<(Position, Velocity)>> {
        let mut poses = self.positions.borrow_mut();
        let mut vels = self.velocities.borrow_mut();

        poses
            .iter_mut()
            .zip(vels.iter_mut())
            .filter(|(e1, e2)| e1.is_some() && e2.is_some())
            .map(|(e1, e2)| (e1.unwrap(), e2.unwrap()))
            .for_each(|elem| println!("{:?}", elem));
    }
}

fn main() {
    let world = World::new();

    world.get_pos_vel();
}

如何将向量的压缩内容作为新内容返回RefCell?那可能吗?

我知道有RefMut::map(),我试图嵌套两个调用map,但没有成功。

标签: rustiteratorborrowing

解决方案


如果你想返回一个新的Vec,那么你不需要将它包装在RefMutor中RefCell

根据您的代码filtermap

pub fn get_pos_vel(&self) -> Vec<(Position, Velocity)> {
    let mut poses = self.positions.borrow_mut();
    let mut vels = self.velocities.borrow_mut();

    poses.iter_mut()
        .zip(vels.iter_mut())
        .filter(|(e1, e2)| e1.is_some() && e2.is_some())
        .map(|(e1, e2)| (e1.unwrap(), e2.unwrap()))
        .collect()
}

替代filter_map

poses.iter_mut()
    .zip(vels.iter_mut())
    .filter_map(|pair| match pair {
        (Some(e1), Some(e2)) => Some((*e1, *e2)),
        _ => None,
    })
    .collect()

如果你真的想的话,你可以RefCell用.RefCell::new


推荐阅读