Rust 프로그래밍 언어를 알아보자

Rust 프로그래밍 언어를 알아보자

Dec 28, 2019    

Rust 프로그래밍 언어

Rust는 범용 목적을 가진 프로그래밍 언어이다. Java, Go 등의 언어가 가지고 있는 Garbage Collection 기능이 없지만, 메모리 안정성을 기대할 수 있다. (이는 Rust의 오너십과 라이프타임이라는 특별한 개념 때문인데 차차 알아보기로 하자) Rust의 메모리 안정성은 다른 언어에서 찾아볼 수 없는 특별한 개념인데, 이 때문에 많은 개발자들에게 관심을 받고 있다.

Rust로 만든 애플리케이션

Github의 Awesome Rust에 방문하면 Rust로 개발한 애플리케이션들이 있다. 이 중 내가 좋아하는 건 bat이다. cat의 기능을 확장하여 syntax highlighting 및 git integration 등의 기능을 사용할 수 있다.

Rust를 배우는 이유

C/C++에 지지 않는 퍼포먼스

Rust는 C/C++만큼 빠르다. 최근에는 일부 벤치마크 결과에서 C/C++에 앞선 퍼포먼스가 나오기 시작했다. Rust 컴파일러는 LLVM을 사용하기 때문에 LLVM의 성능향상이 일어난다면 Rust 컴파일러도 영향을 받게 된다 (즉 더 빨라질 수 있다!).

오너십과 라이프타임

오너십은 Rust를 특별하게 만드는 개념 중 하나이다. 어떤 값을 할당했을 때 이 값의 ‘오너’가 생기고 값의 오너는 항상 하나만 존재한다. 그리고 오너가 스코프를 벗어났을 때 값은 메모리에서 사라진다. 그리고 이는 컴파일 타임에서 체크한다. 아래 코드를 보자.

fn main() {
  // 1. String 타입의 변수를 선언했다. 오너십은 'shawn' 변수에게 있다.
  let shawn = String::from("Shawn");

  hello(shawn);        // 2. shawn 변수의 오너십이 'hello' 함수에게 이동되었다.

  do_something(shawn); // 5. 에러 발생, 이미 main 함수는 name의 오너십을 잃었다.
}

fn hello(name: String) {
  println!("Hello, {}!", name); // 3. 'shawn'의 값을 전달받은 함수는 해당 변수의 오너십을 가지고 있다.
                                // 4. 함수가 종료되는 시점에 'shawn'의 값은 사라진다.
}

fn do_something(s: String) {
  // do something...
}

변수에 대한 오너십은 스코프를 벗어나거나 다른 변수로 할당할 때 이동한다. 위 코드에선 ‘shawn’에 대한 오너십이 hello 함수로 이동했기 때문에 더 이상 main함수에선 shawn 변수를 사용할 수 없다.

이런 오너십 체크가 컴파일 타임에 이뤄지기 때문에 Rust에선 dagling pointer에 대한 걱정을 할 필요가 없다.

개발환경 구성하기

Rustup 설치

Rustup은 Rust 언어 컴파일러 및 관련 도구(cargo, RustFormat) 등을 관리해주는 커맨드라인 툴이다. 자신의 OS에 맞는 Rust 컴파일러를 직접 설치할 수 있지만, 향후 버전업이나 다른 버전의 컴파일러를 사용해야 할 경우 Rustup은 비교적 간단한 방법으로 이를 지원한다.

터미널에서 아래 명령 한 줄을 입력하면 Rustup을 설치할 수 있다.💁‍♂️

$ curl https://sh.rustup.rs -sSf | sh

그리고 rustup이 잘 설치되었는지 확인해보자. 아래와 같이 rustup의 버전이 출력되면 설치가 완료된 것이다.

$ rustup --version
rustup 1.17.0 ( )

$ rustup show
Default host: x86_64-apple-darwin

stable-x86_64-apple-darwin (default)
rustc 1.37.0 (eae3437df 2019-08-13)

Cargo를 이용한 프로젝트 구성

Cargo는 Rust의 패키지 매니저다. node.js의 npm과 같은 역할을 한다. cargo init 명령을 통해 쉽게 Rust 프로젝트를 구성할 수 있으며, 패키지 디펜던시도 관리할 수 있다.

$ cargo init
     Created binary (application) package

생성된 프로젝트의 구성을 보면 이미 git 관련 파일이 있는 것을 볼 수 있다. 전역 git 설정으로 git init이 진행된 상태이다.

.
├── .git
├── .gitignore
├── Cargo.toml
└── src
    └── main.rs

Cargo.toml 파일은 프로젝트의 정보와 패키지 디펜던시를 정의한다. Node.js의 package.json 파일과 유사한 역할을 한다. 그리고 src/main.rs는 프로젝트를 실행할 때의 최초 진입점이다. 내용은 간단한 Hello, world를 출력하는 코드이다. 이 프로젝트는 cargo run 명령으로 실행할 수 있다.

$ cargo run
   Compiling rust v0.1.0 (/Users/sshplendid/WALTZ/study/rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.70s
     Running `target/debug/rust`
Hello, world!

VS Code Rust 개발환경

여태까지 vim을 사용해서 Rust 코드를 작성했는데 부족함을 느껴서 최근에 VS Code를 사용하기 시작했다. 개발환경 설정은 Rinthel님의 블로그을 보고 작업했다.