Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 借用循环中使用的可变成员_Rust_Borrow Checker - Fatal编程技术网

Rust 借用循环中使用的可变成员

Rust 借用循环中使用的可变成员,rust,borrow-checker,Rust,Borrow Checker,我想解决的问题是: 给定递归嵌套的数据结构,例如JSON树和指向其中可能不存在的元素的路径,返回元素的可变引用,即最接近给定路径的引用 示例:如果我们有格式为{a:{b:{c:foo}}}的JSON文档和路径a.b.d,我们希望有一个指向存储在键b下的值的可变指针 这是一段代码片段,到目前为止我得到了: 使用std::collections::HashMap; 枚举Json{ 第64号, 布尔布尔, 弦, ArrayVec, ObjectHashMap } 结构指针{ 值:&'a mut Jso

我想解决的问题是:

给定递归嵌套的数据结构,例如JSON树和指向其中可能不存在的元素的路径,返回元素的可变引用,即最接近给定路径的引用

示例:如果我们有格式为{a:{b:{c:foo}}}的JSON文档和路径a.b.d,我们希望有一个指向存储在键b下的值的可变指针

这是一段代码片段,到目前为止我得到了:

使用std::collections::HashMap; 枚举Json{ 第64号, 布尔布尔, 弦, ArrayVec, ObjectHashMap } 结构指针{ 值:&'a mut Json,
路径:Vec我完全误解了你的问题,我应该向你道歉

您不能在一次传递中完成此操作-您需要执行只读传递以查找最近的路径或精确路径,然后执行读写传递以实际提取引用,或者以闭包的形式传递mutator函数

我为您提供了两次通过的方法。请注意,它仍然非常有效:

fn nearest_mut<'a, 'b>(obj: &'a mut Json, path: Vec<&'b str>) -> Pointer<'a, 'b> {
    let valid_path = nearest_path(obj, path);
    exact_mut(obj, valid_path).unwrap()
}
fn exact_mut<'a, 'b>(obj: &'a mut Json, path: Vec<&'b str>) -> Option<Pointer<'a, 'b>> {
    let mut i = 0;
    let mut target = obj;
    for token in path.iter() {
        i += 1;
        // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop
        // this once-per-loop binding makes the scope clearer and circumvents the error
        let target_once = target;
        let target_opt = match *target_once {
            Json::Object(ref mut map) => map.get_mut(*token),
            Json::Array(ref mut list) => match token.parse::<usize>() {
                Ok(t) => list.get_mut(t),
                Err(_) => None,
            },
            _ => None,
        };
        if let Some(t) = target_opt {
            target = t;
        } else {
            return None;
        }
    }
    Some(Pointer {
        path,
        position: i,
        value: target,
    })
}
/// Return a mutable pointer to JSON element having shared
/// the nearest common path with provided JSON.
fn nearest_path<'a, 'b>(obj: &'a Json, path: Vec<&'b str>) -> Vec<&'b str> {
    let mut i = 0;
    let mut target = obj;
    let mut valid_paths = vec![];
    for token in path.iter() {
        // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop
        // this once-per-loop binding makes the scope clearer and circumvents the error
        let target_opt = match *target {
            Json::Object(ref map) => map.get(*token),
            Json::Array(ref list) => match token.parse::<usize>() {
                Ok(t) => list.get(t),
                Err(_) => None,
            },
            _ => None,
        };
        if let Some(t) = target_opt {
            target = t;
            valid_paths.push(*token)
        } else {
            return valid_paths;
        }
    }
    return valid_paths
}
原理很简单——我重复了我在初始问题中编写的方法,以获得最近的有效路径或精确路径


从那里,我将它直接输入到我原始答案中的函数中,因为我确信路径在前面的函数调用中是有效的,所以我可以安全地展开:-

使用一个额外的闭包参数,然后返回一个结果如何?虽然这是一个有趣的答案,但它并不完整-正如最近的名称所示目标不是返回与路径匹配的元素,但当没有匹配的元素时,返回最接近的元素-请阅读我在开头附上的示例。@BartoszSypytkowski编辑了道歉和一些新代码。感谢您指出,我完全错过了它