C.W.K.
Stream
Lesson 03 of 05 · published

함수 시그니처의 Lifetime

~12 min · lifetimes, functions, longest

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

네가 lifetime 을 쓰게 될 제일 흔한 곳은 참조를 받아 하나를 반환하는 함수야. 이게 canonical 예제 — Rust Book 이 쓰는 그거 — 인데, 아이디어 전체를 담고 있어서야.

longest 함수

두 문자열 참조 중 더 긴 걸 반환하는 함수를 써봐. 컴파일러가 벽에 부딪혀: 반환된 참조는 입력 중 하나에서 빌리는데, 어느 쪽 인지가 런타임 비교에 달렸거든. 도움 없이는 출력이 자기가 나온 입력보다 오래 안 산다고 증명 못 해. 그래서 표기해달라고 해.

같은 lifetime, 같은 운명

두 파라미터랑 반환을 같은 'a 로 표기하면 컴파일러한테 말하는 거야: '결과는 두 입력 lifetime 의 겹침 동안 유효해.' 이제 안전을 증명할 수 있어: 두 입력이 살아있는 동안 반환 참조가 유효하고; 하나라도 죽으면 결과를 못 써. 표기는 동작을 안 바꿨어 — 빠진 사실을 제공했을 뿐이야.

lifetime 을 제어하려는 게 아니라 모호함을 푸는 거야. 컴파일러는 이미 모든 게 얼마나 오래 사는지 알아. 'a 는 출력의 유효성이 입력들과 어떻게 관계되는지를 말해줘 — 답이 런타임 로직에 달렸을 때 컴파일러가 못 추론한 관계 말이야.

입력들이 다른 lifetime 일 때

출력이 특정 파라미터 하나에서만 빌리면, 그 하나만 공유 lifetime 이 필요하고; 다른 건 독립일 수 있어. 출력이 어느 입력에서 빌리는지 정밀해지는 게 진짜 기술이야 — 그리고 컴파일러 에러가 거기로 곧장 안내해.

Code

canonical longest 함수·rust
// 두 입력이랑 출력이 lifetime 'a 를 공유:
// 결과는 x 와 y 가 둘 다 살아있는 만큼 유효.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let a = String::from("a long string");
    let result;
    {
        let b = String::from("short");
        result = longest(&a, &b);
        println!("{result}"); // 괜찮음: 둘 다 살아있는 동안 사용
    }
    // println!("{result}"); // 에러: b 가 사라짐, result 가 dangle 가능
}

External links

Exercise

공유 'alongest 를 써봐. 그다음 그게 올바르게 컴파일 실패하는 경우를 만들어: 입력 중 하나가 이미 drop 된 스코프에서 결과를 반환해봐. 에러를 읽고 borrow checker 가 진짜 dangle 을 잡았는지 확인해.
Hint
입력 하나를 안쪽 스코프에 두고, longest 를 부르고, 그 스코프가 끝난 뒤 결과를 쓰려 해봐. 공유 'a 가 결과를 두 입력에 묶으니, 더 짧게 사는 입력의 죽음 이후 결과 사용은 거부돼.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.