Introduction
- Rust는 다른언어들과 다르게 reference의 lifetime에 대해 컴파일 타임에 체크함
- lifetime이 모호한 경우 컴파일에러가 발생하며, 이를 방지하기 위해 lifetime parameter를 사용함
- 기본적으로 모든 reference는 life-time을 가지고 있음
- 그렇지만 기본적으로 컴파일러는 이를 생략할 수 있도록 허용함
fn bar<'a>(...)
- 함수는 generic parameter를
<>
사이에 가질 수 있으며 life-time이 그 중 한 케이스임
<>
는 lifetime을 선언하는 데 사용되며 bar는 하나의 lifetime을 가짐('a)
Borrow checker
let p;
{
let num = 10;
p = #
}
println!("{}",p);
- 위의 코드는 컴파일 에러를 발생시킴. 이는 p가 num의 레퍼런스인데 println이 호출되는 시점에 num의 lifetime이 만료되어 p가 dangling reference가 되기 때문임.
- C의 경우에는 컴파일 에러가 발생하지 않지만 Rust는
Borrow checker
가 이를 확인함
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
} else {
y
}
}
--> src\main.rs:5:33
|
5 | fn longest(x: &str, y: &str) -> &str {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value,
but the signature does not say whether it is borrowed from `x` or `y`
- 위의 예시의 경우 리턴 값이 x일지 y일지 알수 없어서 에러를 발생 시킴
- 이를 해결하기 위해선 아래와 같이 lifetime을 명시해주어야 함
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
- 여기서 a라는 lifetime을 이용하여 두 매개변수의 lifetime을 명시하여 줌
- 주의할 점은 lifetime parameter가 실제 lifetime에 영향을 주지 않음
- 단순히 컴파일러에게 x,y 그리고 리턴값이 최소한 a만큼 lifetime을 갖는다는 정보만 제공. 즉 아래와 같은 경우에는 컴파일 에러가 발생함
fn longest<'a>(x: &str, y: &str) -> &'a str {
let result = String::from("really long string");
result.as_str()
}
Struct and lifetime
- Rust는
&str
과 String
이 존재하며, &str
은 string slice로 고정된 길이를 가지며 변경이 불가능함.
let greeting = "Hello there.";
- "Hello there."은 string literal이며 타입은
&'static str
임
- string literal이란 string sliced로 statically allocated 되기 때문에 컴파일 프로그램 내에 저장되어 실행되는 전체 기간동안 존재함
- greeting binding은 statically allocated 된 string의 reference임
- string slice를 받아드리는 함수는 string literal 또한 받을 것임
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8
}
fn main() {
let name = "Peter";
let age = 27;
let peter = Person { name, age };
println!("{:#?}", peter);
}
#[derive(Debug)]
struct Person {
name: String,
age: u8
}
fn main() {
let name = String::from("Peter"); Peter"; which is &'static str
let age = 27;
let peter = Person { name, age };
println!("{:#?}", peter);
}