前提・実現したいこと
rustの勉強中ですが、自分なりに課題で作っているコードで解決できない問題に当たったので
質問をさせてください。
発生している問題・エラーメッセージ
話を要約すると、for文の中でborrowしてきた値がfor文の外にlifetimeを持っているデータに引き渡せない
という問題です。
error[E0597]: `new_tree_node` does not live long enough --> catalan.rs:91:26 | 91 | stack.push(new_tree_node.borrow_mut()); | ^^^^^^^^^^^^^ borrowed value does not live long enough
該当のソースコード
プログラムの全体像は以下のリンクにあります。
https://github.com/baban/rust_test/blob/master/catalan.rs
要約だけ抜き取ったものを下に張り付けておきます。
このアルゴリズムでは、親のノードと、stackの2つが一時的に子のノードの所有者にならないとツリーは作れないので、RefCellを使って複数の所有者を持てるようにしました。
ただ、borrowしてきた値のlifetimeが短すぎてfor文を抜ける前に死んでしまうのでコンパイルが通りませんでした。
他のアルゴリズムを考えるのも検討したのですが、そもそもC言語やC++では動くはずのアルゴリズムです
そうであればRustでも、コンパイラに釈明を重ねれば動くはずで何かしら私の知識の抜けの問題と思い
軽く本を読みなおしてみたのですが、lifetimeをいじる方法は、関数の引数か構造体にしか言及がありませんでした。
何かしら書き方の問題で動かないだけの様な気がするのですが、教えていただけないでしょうか?
rust
1// vec![ノード,ノード,リーフ,リーフ,ノード,リーフ,リーフ] の様なVectorから 2// stackを使ってツリーを生成します。 3 4struct RefTreeNode<'a> { 5 left: RefTree<'a>, 6 right: RefTree<'a> 7} 8 9enum RefTree<'b> { 10 Node(Ref<'b, RefTreeNode<'b>>), 11 Leaf { value: i32 }, 12 Empty 13} 14 15fn build_tree(path: Vec<i32>) { 16 // pathから要素を一個取り出す 17 // nodeならstackに積む 18 // leafならstackからnodeをpopしてnodeのrightかleft空いている方に紐付ける 19 // nodeの片方しか埋まっていないときはstackにnodeを戻す 20 // nodeの両方が埋まったらstackに戻さない 21 // pathの最後までこの処理を行ったら、最後に持っているnodeがtreeのroot 22 let mut stack = Vec::<RefMut<RefTreeNode>>::new(); 23 let mut parent_node = RefTreeNode { left: RefTree::Empty, right: RefTree::Empty }; 24 let new_tree_node = RefCell::new(RefTreeNode { left: RefTree::Empty, right: RefTree::Empty }); 25 for pnt in path { 26 match pnt { 27 // node 28 2 => { 29 let latest_node = stack.pop(); 30 if let Some(mut parent_node) = latest_node { 31 match parent_node.left { 32 RefTree::Empty => { 33 let new_tree_node = RefCell::new(RefTreeNode { left: RefTree::Empty, right: RefTree::Empty }); 34 // parent_node.left = RefTree::Node(new_tree_node.borrow()); 35 stack.push(parent_node); 36 // stack.push(new_tree_node.borrow_mut()); 37 }, 38 _ => { 39 let new_tree_node = RefCell::new(RefTreeNode { left: RefTree::Empty, right: RefTree::Empty }); 40 // parent_node.left = RefTree::Node(new_tree_node.borrow()); 41 stack.push(parent_node); 42 // stack.push(new_tree_node.borrow_mut()); 43 }, 44 } 45 } else { 46 // 最初のnodeはstackが空なのでココが呼ばれる 47 let new_tree_node = RefCell::new(RefTreeNode { left: RefTree::Empty, right: RefTree::Empty }); 48 // stack.push(new_tree_node.borrow_mut()); 49 } 50 println!("stack length : {}", stack.len()); 51 }, 52 // leaf 53 1 => { 54 let latest_node = stack.pop(); 55 if let Some(mut parent_node) = latest_node { 56 match parent_node.left { 57 RefTree::Empty => { 58 parent_node.left = RefTree::Leaf { value: 4 }; 59 stack.push(parent_node); 60 }, 61 _ => { 62 parent_node.right = RefTree::Leaf { value: 4 }; 63 }, 64 } 65 println!("stack length : {}", stack.len()); 66 } 67 }, 68 _ =>{}, 69 }; 70 } 71}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/01 01:21 編集