Rustのライフタイムが(やっぱり)分からない
ずっと何もしてなかったのだけどなんかフラストレーション溜まってきたのでRustを何でもいいからやろうかあ! って気分になって、ダイクストラ法を実装してみようかと思った。
取り合えず、Rust 2018のモジュールの仕組みを思い出しながら(Rustのモジュールの使い方 2018 Edition版 | κeenのHappy Hacκing Blog)モジュールとしてダイクストラ法をやる場所を作って、それから部品としてのグラフ、ノード、エッジを作ろうと思った。
のだけど、それがもううまくいかない。現行のソースコードは src/dijkstra.rs なんだけど、 cargo clippy
で怒られてしまう。
struct Edge<'a> {
dest: &'a Node<'a>,
cost: usize,
}
struct Node<'a> {
edges: Vec<&'a Edge<'a>>,
solved: bool,
label: &'a str,
}
impl Node<'_> {
fn new<'a>(label: &'a str) -> Node<'a> {
Node {
edges: Vec::new(),
solved: false,
label,
}
}
fn add_edge_to<'a>(&self, dest: &'a Node, cost: usize) {
let edge = &Edge {dest, cost};
self.edges.push(&edge);
}
}
struct Graph<'a> {
nodes: Vec<&'a Node<'a>>,
}
pub fn run() -> Result<(), ()> {
Ok(())
}
% cargo clippy
Checking rust-algorithm v0.1.0 (/home/kitaitimakoto/src/gitlab.com/KitaitiMakoto/rust-algorithm)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/dijkstra.rs:22:21
|
22 | let edge = &Edge {dest, cost};
| ^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 21:20...
--> src/dijkstra.rs:21:20
|
21 | fn add_edge_to<'a>(&self, dest: &'a Node, cost: usize) {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/dijkstra.rs:22:27
|
22 | let edge = &Edge {dest, cost};
| ^^^^
note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 12:11...
--> src/dijkstra.rs:12:11
|
12 | impl Node<'_> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/dijkstra.rs:23:25
|
23 | self.edges.push(&edge);
| ^^^^^
error: aborting due to previous error
error: could not compile `rust-algorithm`.
To learn more, run the command again with --verbose.
こういう所でハマるのは、まさにそのために勉強しているわけなので歓迎なんだけど、それにしても分からん。なんでなんだろう……。
何か教えてくださるという親切な方がいらしたらこちらまでお願いします…… https://gitlab.com/KitaitiMakoto/rust-algorithm/issues
あと、実はこっそりSlackのrust-jpチームにもいます。