PL wiki

Rust

  • 프로그래밍 언어
  • 명령형 프로그래밍 언어

Rust는 성능, 신뢰성, 생산성 등에 초점을 맞춘 시스템 프로그래밍 언어이다.

특징

소유권(OwnerShip)과 수명(Lifetime) 개념을 도입해 GC없는 메모리 관리를 한다.

소유권

Rust에서 관리되는 모든 값(스택 메모리 상의 공간)은 특정 변수(혹은 구조체의 필드명, 매개변수)에 귀속되며 각 변수와 값은 매 순간 일대일로 대응된다. 만약 특정 값을 소유한 이름에 접근이 불가능해지면 그 값의 할당은 해제된다.

{
    let n = 10;
}
// n이 선언된 scope를 벗어나 n에 접근이 불가능하기 때문에 10을 저장하기 위해 할당된 공간이 해제된다.

이를 통해 Rust는 RAII 를 강제하게 된다.

참조와 수명

Rust에서 특정 값을 소유권을 가진 변수외에 접근하는 방법으로 참조가 존재한다. 참조는 크게 가변참조(mutable reference)와 불변참조(immutable reference)로 나뉘는데 그에 대한 규칙은 다음과 같다.

이는 다음과 같은 실수를 막기 위한 규칙이다.

fn add(a : &mut usize) {
    a = a + 1;
}

fn main() {
    let mut a = 3;
    let b = &a; // b를 불변참조로 설정한 시점에서 b가 참조하는 값이 변하지 않기를 기대함을 알 수 있다
    let c = &mut a; // 그러나 만약 여기서 불변참조와 같이 존재하는 가변참조를 생성한다면
    add(c);
    print!(b) // b가 참조하는 값이 이미 변해있을 수 있다
}

위와 같은 코드는 Rust 컴파일러가 컴파일 시점에 그 오류를 잡아낼 수 있다.

한편 Rust는 수명이라는 개념을 통해 Dangling Pointer 문제를 미연에 방지한다. 수명이란 Rust에서 어떤 변수에 접근 가능한 구간이라고 생각할 수 있다. 그리고 모든 변수는 수명과 관련된 다음과 같은 규칙을 따른다.

다음과 같은 예시를 보자.

fn return_ref() -> &usize{
    let b = 7;
    &b
}

fn main(){
    let a = return_ref();
    print!(a); // 이 시점에서 7이라는 값은 이미 사라진 상태이다. 하지만 a는 그 값을 참조하고 있기 때문에 오류가 발생한다
}

위의 코드에서 발생하는 문제는 b라는 변수를 참조하는 변수인 a의 수명이 b의 것보다 길기 때문이다. 따라서 Rust 컴파일러는 해당 코드를 컴파일 하는 과정에서 오류를 낸다.

외부 링크