Demystifying Rust - 컴파일 되면 동작하는 코드다?

Migo·2023년 8월 24일

Demystifying Rust

목록 보기
2/4
post-thumbnail

만약 컴파일 된다면, lifetime annotation에는 아무런 문제가 없다.

위의 명제에 동의하는가? 그렇다면 이 포스트를 읽어보길 바란다.

Rust Compiler는 "의미"를 체크해주지 않는다.

아래의 코드를 보자.

struct CustomIter<'a> {
    remainder: &'a [&'a str],
}

impl<'a> CustomIter<'a> {
    fn next(&mut self) -> Option<&str> {
        if self.remainder.is_empty() {
            None
        } else {
            let string = &self.remainder[0];
            self.remainder = &self.remainder[1..];
            Some(string)
        }
    }
}

fn main() {
    let mut custom_iter: CustomIter<'_> = CustomIter {
        remainder: &vec!["1"],
    };
    assert_eq!(Some("1"), custom_iter.next());
    assert_eq!(None, custom_iter.next());
}

CustomIternext() 호출시 array의 다음 요소를 호출하는 Iterator이다. (Iterator trait은 설명을 위해 구현하지 않았다)

위의 코드는 정상 작동하는 것처럼 보이지만 한 가지 오류가 있다.


fn main() {
    let mut custom_iter: CustomIter<'_> = CustomIter {
        remainder: &vec!["1","2"],
    };
    let elem1 = custom_iter.next();
    let elem2 = custom_iter.next(); // Error!
    if elem1 == elem2 {
        println!("Same value!")
    }
}

변경점은 단지, 이번엔 2개의 요소를 넣었고, value를 두번 엑세스했을 뿐이다. 왜 문제가 발생할까? 물론, lifetime annotation이 "의미상" 잘못되었기 때문이다.

Rust는 편의성을 위해 lifetime annotation elision을 제공한다. 말은 어렵지만, "별 문제 없어 보이면 내가 알아서 할게" 라는 의미이다.

Rust가 알아서 해주는 것을 풀어헤쳐보자.

struct CustomIter<'a> {
    remainder: &'a [&'a str],
}

impl<'a> CustomIter<'a> {
    fn next<'b>(&'b mut self) -> Option<&'b str> {
        if self.remainder.is_empty() {
            None
        } else {
            let string = &self.remainder[0];
            self.remainder = &self.remainder[1..];
            Some(string)
        }
    }
}

문제가 보이는가?

next<'b>(&'b mut self)의 리턴타입 Option<&'b str>은 같은 lifetime을 갖는다.

즉, Option<&'b str>를 얻어서, 해당 lifetime이 drop되기 전에 next()를 다시 한번 호출한다는 것은 mutable reference를 두번 호출하는 것과 같다! 따라서 에러메세지는:

cannot borrow custom_iter as mutable more than once at a time


Lesson learned: 컴파일러는 오직 Memory Safety만을 보장한다.

러스트 컴파일러는 의미상의 정확성을 판단해주지 못한다.

profile
Dude with existential crisis

0개의 댓글