2017-02-28 11 views
4

私は完全に寿命を理解していませんが、bの寿命はselfの前に終わると思います。値が長すぎる

このコードを編集するにはどうすればよいですか?メモリコピーをしますか?私が新しいインスタンスを作った場合、この生涯はこのケースに従わなければなりません。

pub struct Formater { 
    layout: &'static str, 
} 

impl Formater { 
    pub fn new(layout: &'static str) -> Formater { 
     let regex = Regex::new(r"%\{([a-z]+)(?::(.*?[^\\]))?\}").unwrap(); 
     let b = regex.replace_all(layout, "{}"); 

     return Formater { 
      layout: &b, 
     }; 
    } 
} 

エラー:

error: `b` does not live long enough 
    --> src/format.rs:16:22 
    | 
16 |    layout: &b, 
    |     ^does not live long enough 
17 |   }; 
18 |  } 
    |  - borrowed value only lives until here 
    | 
    = note: borrowed value must be valid for the static lifetime... 
+2

'layout 'に'&' static str'の代わりに 'String'を設定する必要があります。 http://stackoverflow.com/questions/24158114/rust-string-versus-str – kennytm

+0

これは私がそれを行うのに役立つことができます。しかし、私はそれを行うためにstr.howを使用したいのですか?rustは生涯を編集することができません。 –

+0

@彭灵俊なぜ '&str'を使いたいのですか? – wimh

答えて

5

関数が戻るとき、そのメモリが解放されるようbの範囲は、new関数です。しかし、その関数からbへの参照を返そうとしています。 Rustでこれを行えるのであれば、その参照を使用する可能性のある唯一のコードはの後にの後に値を使用します。貸借チェッカーがの定義されていない動作から保護しています。

layout&'static strにすると、簡単なことですが、regex.replace_allの動的割り当てメモリが静的であると予想するのは無理です。 unsafeコードに入らなければ、'staticのすべてのものをコンパイル時定数とみなすべきです。たとえば、文字列リテラルです。

他人の意見通り、layoutStringになります。 String&strに似ていますが、の下位にあるstrを所有しています。つまり、Stringを移動すると、その下にあるstrが移動します。 &strは参照番号であり、それが指し示すstrの所有者よりも長生きするものであってはなりません。


あなたは本当にそれが&strになりたい場合は、代替あまり人間工学的なアプローチは、new()の呼び出し側が&strを所有していて、変更可能なリファレンスとしてそれを渡すことです。

pub struct Formatter<'a> { 
    layout: &'a str, 
} 

impl <'a> Formatter<'a> { 
    pub fn new(layout: &'a mut &str) -> Formatter<'a> { 
     let regex = Regex::new(r"%\{([a-z]+)(?::(.*?[^\\]))?\}").unwrap(); 
     *layout = regex.replace_all(layout, "{}"); 

     return Formatter { 
      layout: layout, 
     }; 
    } 
} 

これは、コールスタックアップ問題一つの層を移動し、あなたがnewに渡す参照がnewにより変異されることを意味します。今sがそのようにformatterは限りそれが唯一のmainよりも小さい範囲で使用されているように有効です、mainによって所有され

pub fn main() { 
    let mut s = "blah %{blah}"; 
    { 
     let formatter = Formatter::new(&mut s); 
     println!("{:?}", formatter.layout); // "blah {}" 
    } 
    println!("{:?}", s); // "blah {}" 
} 

全体的には、この方法は面倒だと思うし、正当な理由がない限り、Stringに固執する必要があります。

関連する問題