確認したこと
- ライフタイム通釈を変更するためには、この構造体を扱う関数定義の変更も必要であることを確認した
- ライフタイム通釈の変更により、一旦構造体や関数を通過した後の参照のライフタイムが変わることを確認した
- 各参照にライフタイムを設定した場合は、構造他の作成元の変数ライフタイムが個別に引き継がれた
- 全体に共通のライフタイムを設定した場合は、全ての参照の中で最短のライフタイムが全体に適用された
参考にした記事
異なるライフタイム<'a,'b,'c>を設定した場合
// 異なるライフタイムを持つ参照を要素に持つ構造体
struct RefHolder<'a, 'b, 'c> {
ref1: &'a i32,
ref2: &'b String,
ref3: &'c Vec<f64>,
}
// RefHolder を引数に受け取り、そのまま返す関数
fn return_ref_holder<'a,'b,'c>(holder: RefHolder<'a,'b,'c>) -> RefHolder<'a, 'b, 'c> {
holder
}
fn main() {
let num = 10;
let ref_num: &i32;
{
let text = String::from("Hello, Rust!");
let ref_text: &String;
{
let numbers = vec![1.0, 2.0, 3.0];
let ref_numbers: &Vec<f64>;
{
let holder = RefHolder {
ref1: &num,
ref2: &text,
ref3: &numbers,
};
let returned_holder = return_ref_holder(holder);
// 構造体の参照を利用して値を出力
println!("Ref1: {}, Ref2: {}, Ref3: {:?}", returned_holder.ref1, returned_holder.ref2, returned_holder.ref3);
// 構造体を一回経由してからスコープ外の可変参照を初期化
ref_num = returned_holder.ref1;
ref_numbers = returned_holder.ref3;
ref_text = returned_holder.ref2;
}
println!("ref_numbers: {:?}", ref_numbers);
}
println!("ref_text: {}", ref_text);
}
println!("ref_num: {}", ref_num);
}
Ref1: 10, Ref2: Hello, Rust!, Ref3: [1.0, 2.0, 3.0]
ref_numbers: [1.0, 2.0, 3.0]
ref_text: Hello, Rust!
ref_num: 10
単一のライフタイム<'a>を設定した場合
// 同じライフタイムを持つ参照を要素に持つ構造体
struct RefHolder<'a> {
ref1: &'a i32,
ref2: &'a String,
ref3: &'a Vec<f64>,
}
// RefHolder を引数に受け取り、そのまま返す関数
fn return_ref_holder<'a>(holder: RefHolder<'a>) -> RefHolder<'a> {
holder
}
fn main() {
let num = 10;
let ref_num: &i32;
{
let text = String::from("Hello, Rust!");
let ref_text: &String;
{
let numbers = vec![1.0, 2.0, 3.0];
let ref_numbers: &Vec<f64>;
{
let holder = RefHolder {
ref1: &num,
ref2: &text,
ref3: &numbers,
};
let returned_holder = return_ref_holder(holder);
// 構造体の参照を利用して値を出力
println!("Ref1: {}, Ref2: {}, Ref3: {:?}", returned_holder.ref1, returned_holder.ref2, returned_holder.ref3);
// 構造体を一回経由してからスコープ外の可変参照を初期化
ref_num = returned_holder.ref1;
ref_numbers = returned_holder.ref3;
ref_text = returned_holder.ref2;
}
println!("ref_numbers: {:?}", ref_numbers);
}
// println!("ref_text: {}", ref_text); //エラーになるので呼び出せない
}
// println!("ref_num: {}", ref_num); //エラーになるので呼び出せない
}
Ref1: 10, Ref2: Hello, Rust!, Ref3: [1.0, 2.0, 3.0]
ref_numbers: [1.0, 2.0, 3.0]