[Rust] Lifetime

0xDave·2022년 6월 28일
0

Rust

목록 보기
12/16
post-custom-banner

모든 변수와 함수는 생명주기를 가진다. 컴파일러는 변수와 함수 및 레퍼런스의 생명주기를 판단하고 시간적 관점에서 논리적 오류가 없는지 확인한다.

Lifetime 은 시간적 측면에서의 Generic이라고 할 수 있다. 일반적으로 Generic은 u32, i32, 공통의 타입을 나타내는 T 등 타입을 미리 정해줄 수 있지만, Lifetime 은 컴파일 될 때 결정된다.

간단한 예제


fn main() {
    {
        let r;                // ---------+-- 'a
                              //          |
        {                     //          |
            let x = 5;        // -+-- 'b  |
            r = &x;           //  |       |
        }                     // -+       |
                              //          |
        println!("r: {}", r); //          |
    }                         // ---------+
}

x 의 값을 참조하는 r 을 바깥쪽 scope에서 출력하려고 한다. 그런데 x 의 lifetime이 안쪽 scope를 벗어나면 끝나기 때문에, r 은 출력될 수 없다. 따라서 r 의 생명주기와 x 의 생명주기에서 논리적 오류가 발생하며 아래처럼 사용해야 한다.

fn main() {
    {
        let x = 5;            // ----------+-- 'b
                              //           |
        let r = &x;           // --+-- 'a  |
                              //   |       |
        println!("r: {}", r); //   |       |
                              // --+       |
    }                         // ----------+
}



예제2


fn main() {
    let string1 = String::from("abcd");
    let string2 = "xyz";

    let result = longest(string1.as_str(), string2);
    println!("The longest string is {}", result);
}

fn longest<'a>(x: &'a str, y: &'b str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

lifetime에서 중요한 것은 언제 시작했냐가 아니라 수명이 언제 끝나는지다. string1string2의 lifetime 시작은 다르지만(string1이 먼저 시작), 같은 함수에서 리턴되는 시점은 같다.

즉, string1string2의 생명주기가 동시에 끝나기 때문에 &'a str 또는 &'b str 로 리턴하면 오류가 나며 아래 처럼 하나로 통일해줘야 한다.

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}


만약 생명주기가 다르다면?


생명주기가 모두 다르다면, 'a 는 어떤 변수의 생명주기를 따라갈까? 생명주기가 다를 때는 가장 짧은 생명주기를 공통분모로 가져간다. 이해를 돕기 위해 벤 다이어그램으로 나타내봤다. 예제 코드를 조금 변경해서 Result, String2, String1 순으로 생명주기가 짧다면(Result의 생명주기가 가장 짧다고 가정) 공통분모가 되는 Result의 생명주기를 'a 로 가져간다.

profile
Just BUIDL :)
post-custom-banner

0개의 댓글