関数
[省略]を無視すると、寿命付きの関数シグネチャにはいくつかの制約があります。
- 任意の参照には寿命が付与されていなければなりません。
- 返される任意の参照は入力と同じ寿命を持たなければなりません。または
static
でなければなりません。
また、入力なしで参照を返すと、無効なデータを参照する参照が返される場合があるため、禁止されています。次の例では、寿命付きの関数のいくつかの有効な形式を示しています。
// 寿命 `'a` を持つ 1 つの入力参照で、これは少なくとも関数と同じ期間だけ生存しなければなりません。
fn print_one<'a>(x: &'a i32) {
println!("`print_one`: x is {}", x);
}
// 寿命付きで可変参照も可能です。
fn add_one<'a>(x: &'a mut i32) {
*x += 1;
}
// 異なる寿命を持つ複数の要素。この場合、両方が同じ寿命 `'a` を持っていても問題ありませんが、
// より複雑な場合には、異なる寿命が必要になることもあります。
fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {
println!("`print_multi`: x is {}, y is {}", x, y);
}
// 渡された参照を返すことは許されます。ただし、正しい寿命を返さなければなりません。
fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }
//fn invalid_output<'a>() -> &'a String { &String::from("foo") }
// 上記は無効です。`'a` は関数よりも長く生存しなければなりません。
// ここで、`&String::from("foo")` は `String` を作成し、その後参照を作成します。
// その後、スコープを抜けるとデータが破棄され、返される無効なデータへの参照が残ります。
fn main() {
let x = 7;
let y = 9;
print_one(&x);
print_multi(&x, &y);
let z = pass_x(&x, &y);
print_one(z);
let mut t = 3;
add_one(&mut t);
print_one(&t);
}