https://doc.rust-lang.org/book/second-edition/
Apache License Version 2.0
Generic Types, Traits, and Lifetimes
Validating References with Lifetimes
referenceにはかならずlifetime(寿命)という,referenceが有効であるスコープをもっているが,大方の場合それは明示されずコンパイラに推測される.lifetimeを特に指定する場合には,generic lifetime parametersを使う.lifetimeはRust独特の機能であって,時に非常に重要なので,この章でその基本的な概念を述べた後,19章で応用的なlifetimeの扱い方を学ぶ.
Lifetime Prevent Dangling References
dangling(宙ぶらりん) referenceは,すでに意味を失った変数へのreferenceで,これを放置すると,あるデータにアクセスしようとして他のデータにアクセスしてしまうことがある.lifetimeの目的はdanglin referenceが出来るのを防ぐことである.
例えばlist 10-16では内側の{ }で定義されたx
へのreferenceをr
に代入しているが,x
は内側の{ }が終了すると同時に消えてしまうので,その時点でr
も有効ではなくなる.つまりx
のlifetimeは内側の{ }の中で,r
のlifetimeは外側の{ }の中だから,その外でのreferenceは無効になる.
list 10-16
{
let r;
{
let x = 5;
r = &x;
}
println!("r: {}", r);
}
The Borrow Checker
list 10-16にlifetimeの注釈を加えてみる.
list 10-17
{
let r; // -------+-- 'a
// |
{ // |
let x = 5; // -+-----+-- 'b
r = &x; // | |
} // -+ |
// |
println!("r: {}", r); // |
// |
// -------+
}
r
のlifetimeを'a
, x
のlifetimeを'b
で書いた.コンパイラはそれぞれのlifetimeを比較し,r
が“`x““をborrowしているのを見つけて,エラーを出す.
list 10-18はdangling referenceを持たず,正常にコンパイルできる.
list 10-18
{
let x = 5; // -----+-- 'b
// |
let r = &x; // --+--+-- 'a
// | |
println!("r: {}", r); // | |
// --+ | rustでは,宣言した順とは逆順に
} // -----+ 変数が無効化されていくのだった
Generic Lifetimes in Functions
2つのstring sliceを引数に与えて,長い方のstring sliceを返す関数longest
を考える.
longest
の実装は後回しにして,例えばlongeest
はlist 10-19のように利用できる.
src/main.rs list 10-19
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
は正常に動けば”abcd”を出力するはずだ.
list 10-20は longest
の案だが,コンパイルできない.
src/main.rs list 10-19
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
} else {
y
}
}
shell
error[E0106]: missing lifetime specifier
|
1 | fn longest(x: &str, y: &str) -> &str {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the
signature does not say whether it is borrowed from `x` or `y`
エラーメッセージは返り値のreferenceがx, y
どちらを指せばいいのかわからないと言っている.しかしプログラマもx
, y
のどちらが長いかは事前にわからないし,与えられる引数のlifetimeがどうであるかもわからない.そこで,generic lifetime parameterによってrefereneたちの間の関係性を記述し,borrow checkerを助けることにする.
Lifetime Annotation Syntax
lifetime annotationは変数のlifetimeそのものを変えることはできないが,複数のreferenceを関連付けることが出来る.構文としては,アポストロフィ`'
とそれに続くlifetime parameterの名前(ふつう小文字1文字)を書く.'a
が最も使われる書き方である.lifetime annotation自体は,referenceの&の直後に書く.たとえば
&i32 // a reference
&'a i32 // a reference with an explicit lifetime
&'a mut i32 // a mutable reference with an explicit lifetime
などと書く.
0 件のコメント:
コメントを投稿