러스트에서 라이프타임(Lifetime) 은 참조자의 유효 기간을 컴파일러가 추론하도록 돕는 개념입니다.
라이프타임을 정의할 때 'a 같은 형태로 사용합니다.
fn example<'a>(param: &'a str) -> &'a str {
param
}
'a: 라이프타임 매개변수(변수처럼 생겼지만, 생명 주기를 나타냄)param: &'a str: param이 'a라는 라이프타임을 따르는 참조자임을 의미.-> &'a str: 반환값 역시 'a 라이프타임을 가짐.함수에서 라이프타임을 지정해야 하는 경우가 있습니다.
fn longest(s1: &str, s2: &str) -> &str { // ❌ 에러 발생!
if s1.len() > s2.len() {
s1
} else {
s2
}
}
✅ 왜 에러가 발생하는가?
컴파일러가 s1과 s2의 라이프타임이 다를 수 있기 때문에 어떤 라이프타임을 반환해야 하는지 결정할 수 없음.
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s1.len() > s2.len() {
s1
} else {
s2
}
}
설명:
'a는 s1과 s2가 같은 라이프타임을 가짐을 의미.&'a str은 s1과 s2 중 하나의 참조자를 반환하지만, 두 값 중 긴 라이프타임을 따라가게 됨.✅ 이제 컴파일 가능!
구조체 내부의 참조자에도 라이프타임을 명시해야 합니다.
struct ImportantExcerpt {
part: &str, // ❌ 에러 발생!
}
✅ 라이프타임을 추가하여 해결
struct ImportantExcerpt<'a> {
part: &'a str, // 'a 라이프타임을 가짐
}
fn main() {
let text = String::from("Hello, Rust!");
let excerpt = ImportantExcerpt { part: &text };
println!("{}", excerpt.part);
}
이렇게 하면 excerpt.part는 text의 라이프타임을 따르게 됨.
러스트는 일반적인 패턴을 따라 라이프타임을 자동으로 추론할 수 있음.
fn first_word(s: &str) -> &str { // 라이프타임 명시 안 해도 됨
let bytes = s.as_bytes();
let index = bytes.iter().position(|&c| c == b' ').unwrap_or(s.len());
&s[..index]
}
✅ 컴파일러가 자동으로 s와 반환값이 동일한 라이프타임을 가짐을 추론
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str { ... }
s1과 s2가 서로 다른 라이프타임을 가질 가능성이 있으므로 명시해야 함.📌 러스트의 라이프타임은 복잡해 보일 수 있지만, 기본 개념을 이해하면 함수나 구조체에서 참조자를 안전하게 사용할 수 있도록 도와준다.