有没有办法避免一次多次借用`*branch`作为可变的

问题描述 投票:0回答:1

我正在尝试实现逻辑以如下所示的 json 作为输入

[{"key": "a", "children": [{"key": "a1", "children": [{"key": "a11", "children": []}]}]}, {"key": "b", "children": [{"key": "b1", "children": [{"key": "b11", "children": []}]}]}] 

预期输出是

{"a": {"a1": {"a11": ""}}, "b": {"b1": {"b11": ""}}}

我的主要功能如下

use serde_json::{json, Value};
use std::{collections::VecDeque};

fn convert_tree(lst: &Vec<serde_json::Value>) -> serde_json::Value {
    let mut tree = serde_json::Map::new();
    let mut queue = VecDeque::new();
    queue.push_back((lst,  &mut tree));
    while let Some((entries, branch)) = queue.pop_front() {
        for entry in entries {
            let key = entry["key"].as_str().unwrap();
            let children = entry["children"].as_array();
            if let Some(children) = children {
                let child_branch = serde_json::Map::new();
                branch.insert(key.to_owned(), serde_json::Value::Object(child_branch));
                let mut branch_ref = branch.get_mut(key).unwrap().as_object_mut().unwrap();
                queue.push_back((children, &mut branch_ref));
            } else {
                branch.insert(key.to_owned(), serde_json::Value::String("".to_owned()));
            }
        }
    }
    serde_json::Value::Object(tree)
}


#[test]
fn test_convert_tree(){
    let a_str = r#"[{"key": "a", "children": [{"key": "a1", "children": [{"key": "a11", "children": []}]}]}, {"key": "b", "children": [{"key": "b1", "children": [{"key": "b11", "children": []}]}]}]"#;
    let v: Vec<serde_json::Value>= serde_json::from_str(a_str).unwrap();
    println!("{:#?}", v);
    let zed = convert_tree(&v);
}

cargo test --package flashlight --example test_serde_json2 -- test_convert_tree --exact --nocapture
遇到错误

error[E0499]: cannot borrow `*branch` as mutable more than once at a time
  --> examples/test_serde_json2.rs:68:17
   |
68 |                 branch.insert(key.to_owned(), serde_json::Value::Object(child_branch));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
69 |                 let mut branch_ref = branch.get_mut(key).unwrap().as_object_mut().unwrap();
   |                                      ------------------- first mutable borrow occurs here
70 |                 queue.push_back((children, &mut branch_ref));
   |                 -------------------------------------------- first borrow later used here

error[E0499]: cannot borrow `*branch` as mutable more than once at a time
  --> examples/test_serde_json2.rs:69:38
   |
62 |     while let Some((entries, branch)) = queue.pop_front() {
   |                                         ----------------- first borrow used here, in later iteration of loop
...
69 |                 let mut branch_ref = branch.get_mut(key).unwrap().as_object_mut().unwrap();
   |                                      ^^^^^^^^^^^^^^^^^^^ `*branch` was mutably borrowed here in the previous iteration of the loop

error[E0597]: `branch_ref` does not live long enough
  --> examples/test_serde_json2.rs:70:44
   |
62 |     while let Some((entries, branch)) = queue.pop_front() {
   |                                         ----------------- borrow later used here
...
70 |                 queue.push_back((children, &mut branch_ref));
   |                                            ^^^^^^^^^^^^^^^ borrowed value does not live long enough
71 |             } else {
   |             - `branch_ref` dropped here while still borrowed

error[E0499]: cannot borrow `*branch` as mutable more than once at a time
  --> examples/test_serde_json2.rs:72:17
   |
62 |     while let Some((entries, branch)) = queue.pop_front() {
   |                                         ----------------- first borrow later used here
...
69 |                 let mut branch_ref = branch.get_mut(key).unwrap().as_object_mut().unwrap();
   |                                      ------------------- first mutable borrow occurs here
...
72 |                 branch.insert(key.to_owned(), serde_json::Value::String("".to_owned()));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here

Some errors have detailed explanations: E0499, E0597.
For more information about an error, try `rustc --explain E0499`.
warning: `flashlight` (example "test_serde_json2" test) generated 1 warning
error: could not compile `flashlight` due to 4 previous errors; 1 warning emitted
rust depth-first-search
1个回答
0
投票

对于此类问题,最简单的方法通常是递归。

fn convert_tree(lst: &[serde_json::Value]) -> serde_json::Value {
    let tree = lst
        .iter()
        .map(|item| {
            let key = item["key"].as_str().unwrap().to_owned();
            let children = if let Some(children) = item["children"].as_array() {
                convert_tree(children)
            } else {
                Value::String("".to_owned())
            };
            (key, children)
        })
        .collect();

    serde_json::Value::Object(tree)
}

© www.soinside.com 2019 - 2024. All rights reserved.