2016-12-05 8 views
4

と形質とメソッドの互換性がない私は可変構造体を含んで寿命と構造体の世界に進出しています:紛らわしいエラーメッセージ

enum Resources { 
    Food, 
    Wood, 
    Tools, 
    Ore, 
    Metal, 
} 

struct ResourceEntry { 
    resource: Resources, 
    amount: i32, 
} 

impl ResourceEntry { 
    fn new(resource: Resources, amount: i32) -> ResourceEntry { 
     ResourceEntry { 
      resource: resource, 
      amount: amount, 
     } 
    } 
} 

trait Agent { 
    fn new<'a>(&'a mut Vec<ResourceEntry>) -> Self; 
} 

struct Miner<'a> { 
    inventory: &'a mut Vec<ResourceEntry>, 
} 

impl<'a> Agent for Miner<'a> { 
    fn new(starting_resource: &'a mut Vec<ResourceEntry>) -> Miner { 
     Miner { inventory: starting_resource } 
    } 
} 

fn main() { 
    let mut resource = ResourceEntry::new(Resources::Food, 3); 
    let mut vec = vec![resource]; 
    let miner: Miner = Miner::new(vec); 

    miner.perform(); 
} 

私は私がすることはできません、次のエラー

error[E0308]: method not compatible with trait 
    --> other.rs:47:5 
    | 
47 |  fn new(starting_resource: &'a mut Vec<ResourceEntry>) -> Miner 
    | ^lifetime mismatch 
    | 
    = note: expected type `fn(&'a mut std::vec::Vec<ResourceEntry>) -> Miner<'a>` 
    = note: found type `fn(&'a mut std::vec::Vec<ResourceEntry>) -> Miner<'a>` 
note: the lifetime 'a as defined on the block at 48:4... 
    --> other.rs:48:5 
    | 
48 |  { 
    | ^
note: ...does not necessarily outlive the lifetime 'a as defined on the block at 48:4 
    --> other.rs:48:5 
    | 
48 |  { 
    | ^
help: consider using an explicit lifetime parameter as shown: fn new(starting_resource: &'a mut Vec<ResourceEntry>) -> Miner 
    --> other.rs:47:5 
    | 
47 |  fn new(starting_resource: &'a mut Vec<ResourceEntry>) -> Miner 
    | ^

を取得私の人生はコンパイラが私に言っていることを頭の中で包んでいます。エラーメッセージは、私がやっていることを正確に行うことを言っています。たぶん私は誤解していますが、寿命はaで、寿命はaと一致しません。私は借用とオーナーシップをかなりよく理解していると思ったが、他のオブジェクトを参照する明示的なライフタイムとオブジェクトの使用は混乱している。

は私が正しく寿命を受け入れるために、新たな取得とのトラブルがあった問題

fn new<'a>(&'a mut Vec) -> Self;

であり、これはあなたがルーストにやるべきものではない場合、私は思ったんだけど?

答えて

6

これはかなりエラーメッセージです。私はあなたにお勧めします。to report it。あなたは...

trait Agent { 
    fn new<'a>(&'a mut Vec<ResourceEntry>) -> Self; 
} 

struct Miner<'b> { 
    inventory: &'b mut Vec<ResourceEntry>, 
} 

impl<'c> Agent for Miner<'c> { 
    fn new(starting_resource: &'c mut Vec<ResourceEntry>) -> Miner { 
     Miner { inventory: starting_resource } 
    } 
} 

をあなたの一般的な寿命のパラメータ名を変更する場合は、より良いエラーを取得:implブロックに生涯を追加

error[E0308]: method not compatible with trait 
    --> src/main.rs:32:5 
    | 
32 |  fn new(starting_resource: &'c mut Vec<ResourceEntry>) -> Miner { 
    | ^lifetime mismatch 
    | 
    = note: expected type `fn(&'a mut std::vec::Vec<ResourceEntry>) -> Miner<'c>` 
    = note: found type `fn(&'c mut std::vec::Vec<ResourceEntry>) -> Miner<'c>` 

それぞれに寿命を指定するための速記ではありません関数;彼らは異なるスコープを持っています。

fn new<'a>(&'a mut Vec<ResourceEntry>) -> Self; 

それ寿命ではありませんは出力のどこにでもを使用:あなたは何をしようとする意味がないことがわかります。代わりに、あなたは一生の特性に役割を果たして行う必要があります。

trait Agent<'a> { 
    fn new(&'a mut Vec<ResourceEntry>) -> Self; 
} 

impl<'c> Agent<'c> for Miner<'c> { 
    fn new(starting_resource: &'c mut Vec<ResourceEntry>) -> Miner<'c> { 
     Miner { inventory: starting_resource } 
    } 
} 

Just so I know exactly what happened, the implementation of Agent for Miner wasn't compatible because the trait Agent didn't have a lifetime associated with it. So when it was trying to compile new in the implementation, it found that it had a lifetime from the Agent::new but a was a random other lifetime it couldn't figure out since that lifetime wasn't in the output.

の種類の。 newの実装には、特性定義の間に生涯パラメータ(fn new<'x>)がないため、互換性がありませんでした。 newに寿命を追加すると、その問題は "解決"されますが、コンパイルしないか、必要な作業を行わないことになります。

The lifetime at the trait level allows you to associated the lifetime in the impl block

特性レベルでの寿命は、特性を実装するタイプを生涯にわたってパラメータ化できることを意味します。その特性はまた、その生涯について知るだろう。

and your able to say that the agent will have the same lifetime as the miner?

あなたはコンセプトを理解していると思いますが、この用語は微妙に間違っています。 Minerには、具体的な寿命を有する参照番号 が提供される。これはではなく、Minerの生涯と同じことです!MinerAgentの実装は、提供された有効期間を利用することができますが、Agentはそれ自身の有効期間を持ちません。それは単なる特性です。

これは人間の弱点であり、私たちは物事についてどのように素早く緩やかな話をしています。価値の存続期間は、移転するまでの期間です。 Rustでは、'aは生涯アノテーション/一般的な生涯パラメータであり、これらの値によって参照が含まれます。値が参照で構成されている場合、具体的な有効期間がパラメータを置き換えます。

+0

恐ろしい!それはそれだった。私はエラーを報告することを確認します。 ちょうど私は何が起こったのか正確に知っているので、Agent Agent for Minerとの互換性はありませんでした。だから、実装で新しくコンパイルしようとしていたときに、Agent :: newからの生存期間があったことが判明しました。しかし、生涯が出力にないので、それは分かりませんでした。特性レベルでの寿命は、あなたがimplブロック内の生涯を関連付けることを可能にし、エージェントが鉱夫と同じ寿命を持つと言うことができますか? – Erik

+1

@Erikがより多くのテキストで更新されました。 – Shepmaster

関連する問題