2016-09-24 5 views
0

代わりに、発信者側の機能にボクシングを移動する方法:私はまた、他の構造では、このような構造を保存したい私はいくつかの構造のための特性とその実装してい

trait Named { 
    fn name(&self) -> String; 
} 

struct Americano; 
impl Named for Americano { 
    fn name(&self) -> String { String::from("Caffè Americano") } 
} 

を:

struct Menu { 
    item: Box<Named>, 
} 
impl Menu { 
    pub fn new(item: Box<Named>) -> Self { 
     Menu { item: item } 
    } 
} 

これは、私がmain関数内の構造をボクシングしている場合に完全に機能します:

私はMenuの関数内でボクシングを動かし、のようなものを使用するかどうかは興味があります:私はnew実装しようとしてい

fn main() { 
    let s = Menu::new(Americano); 
} 

impl Menu { 
    pub fn new<T: Named>(b: T) -> Self { 
     Menu { item: Box::new(b) }; 
    } 
} 

を私はエラーを受け取った

error: the parameter type `T` may not live long enough [--explain E0310] 
    --> <anon>:19:23 
    |> 
19 |>   Menu { item : Box::new(b) }; 
    |>      ^^^^^^^^^^^ 
help: consider adding an explicit lifetime bound `T: 'static`... 
note: ...so that the type `T` will meet its required lifetime bounds 

こちらはcode in the playgroundです。あなたの構造体で

答えて

2

struct Menu { 
    item: Box<Named>, 
} 

Box<Named>は、暗黙のlifetime boundを持っており、Box<Named + 'static>に相当します。したがって、これらの要件を満たすには、Menu::setに渡される値も'staticでなければなりません。

impl Menu { 
    pub fn set<T: Named + 'static>(b: T) -> Self { 
     Menu { item: Box::new(b) } 
    } 
} 

もう1つの選択肢は、生涯の境界を受け入れるように構造体を一般化することです。

struct Menu<'a> { 
    item: Box<Named + 'a> 
} 

impl<'a> Menu<'a> { 
    pub fn new(item: Box<Named + 'a>) -> Self { 
     Menu { item: item } 
    } 

    pub fn set<T: Named + 'a>(b: T) -> Self { 
     Menu { item: Box::new(b) } 
    } 
} 
+1

コンパイラは* 'T拘束明示的な寿命を追加することを検討し提案する理由答えは説明:「static' ... * – Shepmaster

+0

は、第二の変形は十分です 、ありがとうございます。 Tがまだ十分に長く生きられないかもしれないとRustが考える理由はまだ不思議です。 私は関数の値の所有権(借りていない)を渡しているし、私は値をボクシングです。 渡された値がどのように破壊される可能性は想像できませんか? –

+0

@seb_odessa:所有権を渡している値は、借用ポインタでも借用ポインタでも構いません。生涯の境界は、コンパイラが、その指示対象よりも長生きするように値を移動しないことをコンパイラが検証するのに役立ちます。 –

関連する問題