라이프타임 — Rust 컴파일러가 참조의 유효 범위를 추적하는 방법

'a가 뭔지 한 번에 이해하기

라이프타임은 Rust에서 가장 혼란스러운 개념 중 하나다. 'a라는 표기를 처음 보면 대체 뭔가 싶다.

핵심은 간단하다. "이 참조는 이 범위 안에서만 유효하다"를 컴파일러에게 알려주는 표식이다.

왜 필요한가

함수가 참조를 반환할 때 문제가 생긴다. 반환된 참조가 입력 참조 중 어느 것과 같은 수명인지 컴파일러가 추론할 수 없는 경우가 있다. 그때 'a로 "이 출력은 이 입력과 같은 수명이다"를 명시한다.

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str

이건 "x와 y 중 짧은 쪽의 수명만큼 반환값이 유효하다"는 뜻이다.

라이프타임 생략 규칙 (Elision)

Rust 1.0부터 3가지 규칙으로 대부분의 라이프타임을 생략할 수 있게 했다. 그래서 실제로 'a를 직접 쓸 일은 생각보다 적다. 구조체에 참조를 담을 때가 가장 흔한 케이스다.

핵심 포인트

1

모든 참조에는 라이프타임이 있다 — 대부분 컴파일러가 자동 추론(elision)

2

함수가 참조를 반환할 때 입출력의 수명 관계를 'a로 명시

3

구조체에 참조를 담을 때도 라이프타임 파라미터 필수

4

컴파일러가 'a 범위를 벗어나는 사용을 감지하면 에러

장점

  • 댕글링 포인터를 컴파일 타임에 100% 차단
  • 런타임 비용 제로 — 모든 검증이 컴파일 타임

단점

  • 'a 문법이 처음엔 직관적이지 않다
  • 복잡한 라이프타임 관계는 코드 가독성을 떨어뜨린다

사용 사례

파서/토크나이저 — 원본 문자열의 슬라이스를 반환하는 함수 캐시 구조체 — 원본 데이터에 대한 참조를 보관