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

Lifetime 표기 문법

~11 min · lifetimes, annotations, syntax

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

lifetime 표기는 처음 보면 외계어 같아: &'a str, fn foo<'a>(...). 문법을 해독해서 무섭지 않게 만들자.

'a 읽기

작은따옴표 뒤에 이름이 오면 lifetime 파라미터 야: 'a 는 'lifetime a' 라고 읽어. 타입의 T 처럼 제네릭 파라미터야 — '어떤 코드 영역' 을 가리키고, 컴파일러가 호출마다 구체적 영역을 채워. &'a str 은 'str 로의 참조, 영역 'a 동안 유효' 라는 뜻이야.

쓰기 전에 선언

타입 제네릭처럼, 쓰기 전에 꺾쇠 안에 lifetime 을 선언해: fn foo<'a>(x: &'a str). 꺾쇠 부분이 이름을 도입하고; &'a str 이 그걸 써. fn foo<T>(x: T) 랑 정확히 평행이야 — lifetime 은 타입이 아니라 영역에 대한 제네릭이야.

이름은 임의고, 관계가 전부야. 'a, 'b, 'life — 글자 자체는 아무 의미 없어. 중요한 건 어떤 참조들이 같은 lifetime 이름을 공유하느냐야, 그게 걔들의 유효성을 함께 묶거든.

표기가 약속하는 것

두 파라미터를 같은 'a 로 쓰면 컴파일러한테 말하는 거야: '이것들을 한 영역 공유로 다뤄 — 출력은 두 입력이 둘 다 살아있는 동안만 유효해.' 어떤 수명도 늘리거나 줄이는 게 아니라; 컴파일러가 호출 지점마다 강제할 제약을 진술하는 거야.

Code

문법 해독·rust
// <'a> 가 lifetime 을 선언; &'a str 이 그걸 씀.
// 이건 말해: 반환된 참조가 두 입력이 둘 다 살아있는 만큼 산다.
fn pick<'a>(first: &'a str, second: &'a str, use_first: bool) -> &'a str {
    if use_first { first } else { second }
}

fn main() {
    let a = String::from("alpha");
    let b = String::from("beta");
    let chosen = pick(&a, &b, true);
    println!("{chosen}");
}

External links

Exercise

pick 함수에서 파라미터 하나를 다른 lifetime 으로 바꿔봐 ('a'b 둘 다 선언하고 second'b 를 줘). 그래도 second 를 반환하려 하고 컴파일러 에러를 읽어. 컴파일러가 놓친 관계가 뭐야?
Hint
출력이 &'a str 로 선언됐는데 'b 파라미터를 반환하면, 컴파일러가 'b 데이터가 'a 보다 오래 산다고 증명 못 해. 표기가 이제 보장 안 되는 걸 말하고 있어 — 그게 에러야.

Progress

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

댓글 0

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

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