2017-07-19 32 views
-1

を書くときT 'が、私はルーストにバイナリ検索ツリーを書き込むしようとしているが、私は何が起こっているか理解できないほど長く生きられないことがあり、パラメータのタイプ `:バイナリ検索ツリー

enum BST<'a, T: Ord> { 
    Leaf, 
    BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> } 
} 

impl<'a, T: Ord> BST<'a, T> { 
    fn new() -> BST<'a, T> { 
     BST::Leaf 
    } 

    fn add(self, val: T) { 
     match self { 
      BST::Leaf => self = BST::BinTree { 
       value: val, 
       left: &mut BST::<'a, T>::new(), 
       right: &mut BST::<'a, T>::new() 
      }, 
      BST::BinTree{value: v, left: l, right: r} => if val < v { 
       l.add(val); 
      } else { 
       r.add(val); 
      } 
     } 
    } 
} 

fn main() { 
} 

私はこれをコンパイルしようとすると、私は次のエラーを取得:

enum BST<'a, T: Ord + 'a> { 
    Leaf, 
    BinTree { 
     value: T, 
     left: &'a mut BST<'a, T>, 
     right: &'a mut BST<'a, T> 
    } 
} 

impl<'a, T: Ord + 'a > BST<'a, T> { 
    fn new() -> BST<'a, T> { 
     BST::Leaf 
    } 

    fn add(&mut self, val: T) { 
     match *self { 
      BST::Leaf => *self = BST::BinTree { 
       value: val, 
       left: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>, 
       right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T> 
      }, 
      BST::BinTree{value: ref v, left: ref mut l, right: ref mut r} => if val < *v { 
       l.add(val); 
      } else { 
       r.add(val); 
      } 
     } 
    } 
} 

fn main() { 
} 
:研究の多くを行うと、コンパイラは、私はこのコードを思い付い示唆していることをやった後、

error[E0309]: the parameter type `T` may not live long enough 
--> heap.rs:3:25 
    | 
3 |  BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> } 
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ 
    | 
    = help: consider adding an explicit lifetime bound `T: 'a`... 
note: ...so that the reference type `&'a mut BST<'a, T>` does not outlive the data it points at 
--> heap.rs:3:25 
    | 
3 |  BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> } 
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ 

まあを

しかし、私はまだエラーを取得:

error: borrowed value does not live long enough 
    --> heap.rs:19:16 
    | 
19 |    left: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>, 
    |       ^^^^^^^^^^^^^^^^^^^ does not live long enough 
20 |    right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T> 
21 |   }, 
    |   - temporary value only lives until here 
    | 
note: borrowed value must be valid for the lifetime 'a as defined on the body at 15:27... 
    --> heap.rs:15:28 
    | 
15 | fn add(&mut self, val: T) { 
    | ____________________________^ 
16 | |  match *self { 
17 | |   BST::Leaf => *self = BST::BinTree { 
18 | |    value: val, 
... | 
27 | |  } 
28 | | } 
    | |__^ 

error: borrowed value does not live long enough 
    --> heap.rs:20:17 
    | 
20 |    right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T> 
    |       ^^^^^^^^^^^^^^^^^^^ does not live long enough 
21 |   }, 
    |   - temporary value only lives until here 
    | 
note: borrowed value must be valid for the lifetime 'a as defined on the body at 15:27... 
    --> heap.rs:15:28 
    | 
15 | fn add(&mut self, val: T) { 
    | ____________________________^ 
16 | |  match *self { 
17 | |   BST::Leaf => *self = BST::BinTree { 
18 | |    value: val, 
... | 
27 | |  } 
28 | | } 
    | |__^ 

error: aborting due to 2 previous errors 

は、私は、これはBox ES代わりの参照を用いて固定することができます知っているが、私は運動のために、このようにそれを作りたいです。

+0

'Ord'の横に' T 'の上に '+' a'を置いてみましたか? –

+4

ようこそスタックオーバーフロー!我々は[ここではかなりの努力を払うことを期待している](https://meta.stackoverflow.com/q/261592/155423)。例えば、**コンパイラが示唆していることをやってみた**:*明示的な生存期間を追加することを考えた 'T: 'a' *?そうでなければ、*なぜではないのですか?もしあなたがそうしたら、あなたはそれでどんな問題を抱えていましたか?同様のエラーメッセージを持つ既存の質問も19件あります(https://stackoverflow.com/search?q=%5Brust%5D+The+parameter+type+may+not+live+long+enough+is %3Aq)。誰かがすでに時間をかけて答えているので、それらを読んでください。それ以後何がうまくいかないのか教えてください – Shepmaster

答えて

1

エラーメッセージには、生涯バインドT: 'aを追加することで、その特定のエラーを修正できます。しかし、あなたは何をしようとしているのかが分からないので、他にも多くのエラーが発生します。所有者がいないオブジェクトへの参照を他の場所に格納しようとしています。

ノードに&mut BST::<'a, T>::new()を格納すると、BST::<'a, T>::new()はすぐに破棄される一時的な値を返します。そのため、参照を格納してそれが存続することは期待できません。

参照の代わりに、ノードを子ノードにする必要があります。新しい子ノードを作成するときに、子タイプをleft: Box<BST<T>>に変更し、Box::newを使用してこれを行うことができます。一度これを行うと、すべての'aをすべて取り除くことができ、生涯に関連するエラーは発生しません。

もう1つの問題は、addselfパラメータを消費し、発信者がこれ以上使用できなくなることです。代わりに&mut selfを呼び出して、発信者が所有するツリーを変更できるようにする必要があります。

+0

「自己」との間違いを説明してくれてありがとう。しかし、私が言ったように、私は運動のための参考資料でそれを作りたいと思っています。 –

+1

@DimoChanev私はそれを理解していますが、ノードに所有者がいないため不可能であると説明しました。 – interjay

関連する問題