ライフタイムは完全には理解していませんが、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...
b
のスコープはnew
関数であるため、関数が戻るとそのメモリは解放されます。しかし、その関数からb
への参照を返そうとしています。 Rustこれを許可すると、その参照を使用する可能性のある唯一のコードはそれを使用することになりますafter値は無効です。借用チェッカーがあなたを保護しています- 未定義の動作。
layout
を_&'static str
_にすることは、物事を単純にしているように聞こえますが、_regex.replace_all
_から動的に割り当てられたメモリが静的であると期待するのは無理です。 unsafe
コードに入らない場合は、_'static
_の有効期間内のすべてをコンパイル時の定数と見なす必要があります。たとえば、文字列リテラル。
他の人が言っているように、おそらくlayout
をString
にしたいと思うでしょう。 String
は_&str
_に似ていますが、owns基になる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,
};
}
}
_
これにより、問題がコールスタックの1層上に移動し、new
に渡す参照がnew
によって変更されます。
_pub fn main() {
let mut s = "blah %{blah}";
{
let formatter = Formatter::new(&mut s);
println!("{:?}", formatter.layout); // "blah {}"
}
println!("{:?}", s); // "blah {}"
}
_
現在、s
はmain
が所有しているため、formatter
は、main
よりも小さいスコープでのみ使用される限り有効です。
しかし、全体として、この方法は面倒だと思います。正当な理由がない限り、String
を使用する必要があります。