| ... | ... | |
|---|
| 47 | 47 | } |
|---|
| 48 | 48 | println!("{a}"); |
|---|
| 49 | 49 | } }}}를 실행하면 컴파일 에러가 난다.[* 런타임 에러가 아니다!] 왜냐하면 스코프 안에서 선언 된 a를 수명이 끝난 스코프 밖에서 값을 조회하였기 때문이다. |
|---|
| 50 | ==== 제내릭 라이프타임 ==== |
|---|
| 51 | '''지옥의 시작''' |
|---|
| 52 | {{{#!syntax rust |
|---|
| 53 | fn longest<'a> (s1:&`a str,s2:&`a str) -> &`a str { |
|---|
| 54 | if s1.len() > s2.len() { |
|---|
| 55 | s1 |
|---|
| 56 | } else { |
|---|
| 57 | s2 |
|---|
| 58 | } |
|---|
| 59 | } }}} |
|---|
| 60 | 함수 뒤에 꺽쇠 괄호가 있는 것을 볼 수 있는데 이렇게 생각하면 된다. |
|---|
| 61 | {{{#!syntax rust |
|---|
| 62 | fn any<T> (input:T) { |
|---|
| 63 | //input은 어떤 타입이든 될 수 있음 |
|---|
| 64 | } }}} |
|---|
| 65 | 위의 예시처럼 `a는 어느 라이프타임이든 될 수 있다는 것이다. |
|---|
| 66 | |
|---|
| 67 | 다시 longest로 돌아가보자. 아하 longest 함수의 s1과 s2는 공통된 생명 주기를 가져야하고 리턴값의 생명주기도 같아야하구나.라는 사실을 알수 있다. 왜냐? |
|---|
| 68 | {{{#!syntax rust |
|---|
| 69 | fn main () { |
|---|
| 70 | let s1 = String::new(); |
|---|
| 71 | let result; |
|---|
| 72 | { |
|---|
| 73 | s2 = String::new(); |
|---|
| 74 | result = longest(s1, s2); |
|---|
| 75 | } |
|---|
| 76 | println!("{result}"); |
|---|
| 77 | } }}} |
|---|
| 78 | 만약 위 코드에서 함수가 s2를 리턴한다면 참조가 가리키는 원본인 s2가 죽었는데 result를 조회해서 null pointer가 생겼기 때문이다. |
|---|
| 79 | |
|---|
| 80 | 그러면 의문이 들 것이다. "아니 그러면 런타임 에러를 발생시키면 되잖아." 그런데 러스트는 그걸 하지 말라 만든 언어다. 언어 설계에 모순이 생긴다. |
|---|
| 81 | |
|---|
| 82 | "아니 그러면 애초부터 result를 longest의 리턴으로 못넣게 하면 되잖아." 그게 수명주기 명시다. |
|---|
| 50 | 83 | |
|---|
| 51 | 84 | == 그 외 == |
|---|
| 52 | 85 | * 컴파일 언어이다. |
|---|
| 53 | 86 | * 컴파일 시간에 대부분의 런타임 에러를 잡아낸다. |
|---|