[英]Rust lifetime in closure environment
I want to implement a graph structure in Rust. 我想在Rust中实现图结构。 For this goal, I wrote simple abstractions:
为此,我写了一些简单的抽象:
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
contains vectors of Nodes
and Edges
. Graph
包含Nodes
和Edges
向量。 Every Edge
has a ref to a Node
in the same Graph
. 每个
Edge
在同一Graph
都有对Node
的引用。
I don't know it's a possible write something like this. 我不知道有可能写这样的东西。
I tried to write a static method that builds a new Graph
instance from a JSON representation: 我试图编写一个静态方法,该方法从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!");
}
}
When I compile, I get this error: 编译时,出现以下错误:
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
A possible solution to this problem is to add move
before the closure parameters, but I need the nodes
vector to build the Graph
instance. 该问题的可能解决方案是在闭包参数之前添加
move
,但是我需要nodes
向量来构建Graph
实例。
What am I doing wrong? 我究竟做错了什么?
After some research, I found this article's: Rust doc. 经过一番研究,我发现了这篇文章: Rust doc。 Smart pointers , Users Rust Lang , and I understood my mistakes.
智能指针 , 用户Rust Lang ,我理解我的错误。 The first one: I remove lifetime parameters from structs definitions.
第一个:从结构定义中删除生命周期参数。
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>
}
Second thing: I rewrote the code of from_json
function for using Rc<T>
instead of raw references. 第二件事:我重写了使用
Rc<T>
而不是原始引用的from_json
函数的代码。
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!");
}
}
Now it works. 现在可以了。 Thanks for sharing useful links.
感谢您分享有用的链接。 I found a lot of helpful information about building graph structs in
Rust
such as: Graph structure in Rust 我发现了很多有关在
Rust
构建图结构的有用信息,例如: Rust中的图结构
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.