首页 > 解决方案 > Rust - 返回对结构拥有的 Vec 中元素的可变引用

问题描述

这是我的结构:

pub(crate) struct Graph {
    outbound: HashMap<isize, Vec<isize>>,
    inbound: HashMap<isize, Vec<isize>>,
    edges: Vec<Edge>,
}

以及我尝试过的:

fn get_edge_mut(&mut self, from_id: isize, to_id: isize) -> Result<&mut Edge, GraphError> {
    let mut edges = self
        .edges
        .iter_mut()
        .filter(|edge| edge.get_from() == from_id && edge.get_to() == to_id)
        .collect::<Vec<_>>();
    match edges.len() {
        0 => Err(GraphError(format!(
            "edge from {} to {} does not exist",
            from_id, to_id
        ))),
        1 => Ok(edges[0]),
        _ => panic!(
            "wrong graph structure - edge from {} to {} exists multiple times",
            from_id, to_id
        ),
    }
}

问题在这里:Ok(edges[0])

它失败了cannot return value referencing local variable "edges"

我知道它edges归当前函数所有,我无法返回对它的引用,因为它超出了范围,但是返回对“edges” Vec(结构)中元素的可变引用的更好方法是什么基于某些条件?

标签: rust

解决方案


我建议使用:

    fn get_edge_mut(&mut self, from_id: isize, to_id: isize) -> Result<&mut Edge, GraphError> {
        self.edges.iter_mut()
            .find(|edge| edge.get_from() == from_id && edge.get_to() == to_id)
            .ok_or(GraphError(format!("edge from {} to {} does not exist", from_id, to_id)))
    }

它会跳过您的“错误的图形结构检查”,但如果需要,您可以使用

fn get_edge_mut(&mut self, from_id: isize, to_id: isize) -> Result<&mut Edge, GraphError> {
    let mut edges_matching = self.edges.iter_mut()
        .filter(|edge| edge.get_from() == from_id && edge.get_to() == to_id);

    let edge = edges_matching.next()
        .ok_or(GraphError(format!("edge from {} to {} does not exist", from_id, to_id)));

    assert_eq!(edges_matching.count(), 0,
               "wrong graph structure - edge from {} to {} exists multiple times",
               from_id, to_id);

    edge
}

似乎问题可能源于edges[0]最终调用SliceIndex::index,它基本上返回一个Option<&&mut Edge>,其中 first&实际上是对当前函数的引用。

Trendcl 是对的,edges.pop()也可以。


推荐阅读