我想在Rust中实现图形结构。为了这个目标,我写了简单的抽象:
pub struct Graph<'a> {
pub nodes: Vec<Node>,
pub edges: Vec<Edge<'a>>,
}
#[derive(Debug)]
pub struct Node {
pub id: String,
pub label: String,
}
pub struct Edge<'a> {
pub source: &'a Node,
pub target: &'a Node,
}
Graph
包含Nodes
和Edges
的向量。每个Edge
在同一个Node
中都有Graph
的参考号。
我不知道可能会写这样的东西。
我尝试编写一个静态方法,从JSON表示构建一个新的Graph
实例:
impl<'a> Graph<'a> {
pub fn from_json(json: &String) -> Graph {
if let json::JsonValue::Object(deserialized) = json::parse(json.as_ref()).unwrap() {
let nodes: Vec<Node> = deserialized
.get("nodes")
.unwrap()
.members()
.map(|v| {
if let json::JsonValue::Object(ref val) = *v {
return Node {
id: val.get("id").unwrap().to_string(),
label: val.get("label").unwrap().to_string(),
};
}
panic!("Invalid structure of json graph body.")
})
.collect::<Vec<Node>>();
let edges: Vec<Edge> = deserialized
.get("edges")
.unwrap()
.members()
.map(|v| {
if let json::JsonValue::Object(ref val) = *v {
let source = (*nodes)
.iter()
.find(|&v| v.id == val.get("source").unwrap().to_string())
.unwrap();
let target = (*nodes)
.iter()
.find(|&v| v.id == val.get("target").unwrap().to_string())
.unwrap();
return Edge { source, target };
}
panic!("Invalid structure of json graph body.")
})
.collect::<Vec<Edge>>();
return Graph { nodes, edges };
}
panic!("Incorrect struct of json contains!");
}
}
编译时,我收到此错误:
error[E0373]: closure may outlive the current function, but it borrows `nodes`, which is owned by the current function
--> src/graph.rs:30:22
|
30 | .map(|v| {
| ^^^ may outlive borrowed value `nodes`
31 | if let json::JsonValue::Object(ref val) = *v {
32 | let source = (*nodes).iter().find(|&v| v.id == val.get("source").unwrap().to_string()).unwrap();
| ----- `nodes` is borrowed here
|
help: to force the closure to take ownership of `nodes` (and any other referenced variables), use the `move` keyword
|
30 | .map(move |v| {
| ^^^^^^^^
error: aborting due to previous error
此问题的一个可能解决方案是在闭包参数之前添加move
,但我需要nodes
向量来构建Graph
实例。
我做错了什么?
答案 0 :(得分:0)
经过一番研究,我发现这篇文章是:Rust doc. Smart pointers,Users Rust Lang,我理解了自己的错误。 第一个:我从结构定义中删除了生命周期参数。
use std::rc::Rc;
#[derive(Debug)]
pub struct Graph {
pub nodes: Vec<Rc<Node>>,
pub edges: Vec<Edge>
}
#[derive(Debug)]
pub struct Node {
pub id: String,
pub label: String
}
#[derive(Debug)]
pub struct Edge {
pub source: Rc<Node>,
pub target: Rc<Node>
}
第二件事:我重写了from_json
函数的代码,使用Rc<T>
代替原始引用。
impl Graph {
pub fn from_json(json: & String) -> Graph {
if let json::JsonValue::Object(deserialized) = json::parse(json.as_ref()).unwrap() {
let nodes : Vec<Rc<Node>> = deserialized.get("nodes").unwrap().members()
.map(|v| {
if let json::JsonValue::Object(ref val) = *v {
return Rc::new(Node {
id: val.get("id").unwrap().to_string(),
label: val.get("label").unwrap().to_string()
});
}
panic!("Invalid structure of json graph body.")
}).collect::<Vec<Rc<Node>>>();
let edges : Vec<Edge> = deserialized.get("edges").unwrap().members()
.map(|v| {
if let json::JsonValue::Object(ref val) = *v {
let source = nodes.iter().find(|&v| v.id == val.get("source").unwrap().to_string()).unwrap();
let target = nodes.iter().find(|&v| v.id == val.get("target").unwrap().to_string()).unwrap();
return Edge {
source: Rc::clone(&source),
target: Rc::clone(&target)
};
}
panic!("Invalid structure of json graph body.")
}).collect::<Vec<Edge>>();
return Graph {
nodes,
edges
}
}
panic!("Incorrect struct of json contains!");
}
}
现在它有效。感谢您分享有用的链接。我在Rust
中找到了很多有关构建图形结构的有用信息,例如:Graph structure in Rust