갈루아의 반서재


The Rust Programming Language

Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.


“The Rust Programming Language” (https://doc.rust-lang.org/stable/book) 의 내용을 기반으로 Rust 프로그래밍을 실습하는 포스팅을 게재해보고자 합니다. 먼저 Rust 시작하기(https://doc.rust-lang.org/stable/book/getting-started.html)입니다.



1. 앞으로 Rust 실습에 사용할 아나콘다 가상환경 설치한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
root@localhost:~# conda create -n envrust python=3.5 anaconda
Fetching package metadata: ....
Solving package specifications: .
Package plan for installation in environment /root/anaconda/envs/envrust:
 
The following packages will be downloaded:
 
    package                    |            build
    ---------------------------|-----------------
    openssl-1.0.2j             |                0         3.2 MB
    setuptools-27.2.0          |           py35_0         526 KB
    ------------------------------------------------------------
                                           Total:         3.7 MB
 
The following NEW packages will be INSTALLED:
 
    anaconda:   custom-py35_0
    openssl:    1.0.2j-0
    pip:        8.1.2-py35_0
    python:     3.5.2-0
    readline:   6.2-2
    setuptools: 27.2.0-py35_0
    sqlite:     3.13.0-0
    tk:         8.5.18-0
    wheel:      0.29.0-py35_0
    xz:         5.2.2-0
    zlib:       1.2.8-3
 
Proceed ([y]/n)? y
 
Fetching packages ...
openssl-1.0.2j 100|################################| Time: 0:00:02   1.32 MB/s
setuptools-27. 100|################################| Time: 0:00:01 368.65 kB/s
Extracting packages ...
[      COMPLETE      ]|###################################################| 100%
Linking packages ...
[      COMPLETE      ]|###################################################| 100%
#
# To activate this environment, use:
# $ source activate envrust
#
# To deactivate this environment, use:
# $ source deactivate
#
root@localhost:~# source activate envrust
discarding /root/anaconda/bin from PATH
prepending /root/anaconda/envs/envrust/bin to PATH
(envrust)root@localhost:~
cs



2. Rust를 설치한다.


이하는 우분투 기준으로 플랫폼별 설치는 https://doc.rust-lang.org/book/getting-started.html#platform-support 링크를 참조한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(envrust)root@localhost:~# curl -sSf https://static.rust-lang.org/rustup.sh | sh
rustup: gpg available. signatures will be verified
rustup: downloading manifest for 'stable'
rustup: downloading toolchain for 'stable'
######################################################################## 100.0%
gpg: Signature made 2016년 09월 28일 (수)  using RSA key ID 7B3B09DC
gpg: Good signature from "Rust Language (Tag and Release Signing Key) <rust-key@rust-lang.org>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 108F 6620 5EAE B0AA A8DD  5E1C 85AB 96E6 FA1B E5FE
     Subkey fingerprint: C134 66B7 E169 A085 1886  3216 5CB4 A934 7B3B 09DC
rustup: installing toolchain for 'stable'
rustup: extracting installer
install: creating uninstall script at /usr/local/lib/rustlib/uninstall.sh
install: installing component 'rustc'
install: installing component 'rust-std-x86_64-unknown-linux-gnu'
install: installing component 'rust-docs'
install: installing component 'cargo'
 
    Rust is ready to roll.
 
cs



3. Hello! World! 프로그램을 만들어보자.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(envrust)root@localhost:~# mkdir ~/projects
(envrust)root@localhost:~# cd ~/projects
(envrust)root@localhost:~/projects# mkdir hello_world
(envrust)root@localhost:~/projects# cd hello_world
(envrust)root@localhost:~/projects/hello_world# rustc main.rs
error[E0425]: unresolved name `println`. Did you mean the macro `println!`?
 --> main.rs:2:2
  |
2 |     println ("Hello, world!")
  |     ^^^^^^^
 
error: aborting due to previous error
 
(envrust)root@localhost:~/projects/hello_world# rustc main.rs
(envrust)root@localhost:~/projects/hello_world# ./main
Hello, world!
(envrust)root@localhost:~/projects/hello_world#
 
cs


※ 윈도우 환경에서는 ~ 가 작동하지 않음에 유의할 것


4. Rust 프로그램의 해부학


Hello World! 프로그램의 생김새를 살펴보자.

fn main() {

}

위의 코드는 함수의 기본 구조를 나타낸다. 위의 mian 함수는 특별한 함수로, 모든 Rust 프로그램의 시작을 나타낸다.

특별한 argument 가 있다면 ( ) 사이에 들어가야하고, 함수의 body는 { } 로 감싸야한다.


다음 라인을 살펴보자.

 println!("Hello, world!");

println!()은 스크린에 텍스트를 출력해주데, ! 에 주의할 필요가 있다.

println!()은 Rust macro로 함수대신 매크로를 호출한다는 의미이다.

함수라면 !가 없는  prinlin() 의 형태여야 한다.

그리고 "Hello, world!" 는 string 으로 println!의 argument 이다.



5. 컴파일과 실행


실행전에 먼저 컴파일부터 해야한다.

1
(envrust)root@localhost:~/projects/hello_world# rustc main.rs
cs

컴파일을 하고 나면 아래와 같이 실행가능한 파일을 생성해낸다.

1
2
(envrust)root@localhost:~/projects/hello_world# ls
main  main.rs
cs

그리고 나서 실행한다.

1
2
(envrust)root@localhost:~/projects/hello_world# ./main
 
cs

Rust는 컴파일되고 난 이후에는 러스트가 설치되지 않은 환경에서라도 실행이 가능한 ahead-of-time compiled 언어다.




6. Hello, Cargo!

Rust 프로젝트를 관리하기 위해 Cargo 를 사용해보자.

Cargo는 아래의 기능을 수행한다.

- building code

- downloading the libraries you code depends on

- building those libraries


Cargo 는 Rust 설치시 같이 설치된다.

1
2
3
 
(envrust)root@localhost:~/projects/hello_world# cargo --version
cargo 0.13.0-nightly (109cb7c 2016-08-19)
cs



7. Converting to Cargo


그럼 Hello world 프로그램을 Cargo 로 컨버터해보자.


1) 소스 디렉토리 생성 & 실행파일 제거

1
2
3
(envrust)root@localhost:~/projects/hello_world# mkdir src
(envrust)root@localhost:~/projects/hello_world# mv main.rs src/main.rs
(envrust)root@localhost:~/projects/hello_world# rm main
cs

Cargo 는 소스파일이 src 디렉토리에 있다고 가정한다.

top-level 프로젝트에 해당 디렉토리를 둔다

앞서 만든 main.rs 파일을 소스 디렉토리로 옮기고 컴파일한 main 파일을 삭제한다.


2) 환경설정 파일 생성

Cargo.toml 파일을 만든다(반드시 대문자 C 로 시작해야 한다).

이 파일은 TOML (Tom's Obvious, Minimal Language) 포맷으로, INI 포맷과 유사한 것이다.

package 기본적인 구성은 아래위와 같다.

1
2
3
4
5
[package]
 
name = "hello_world"
version = "0.0.1"
authors = [ "Your name <you@example.com>" ]
cs


프로젝트 루트 디렉토리에 있는 Cargo.toml  파일을 저장하고 Hello World program을 빌드할 준비가 된 것이다.

아래와 같이 빌드한다. Hello, world! 출력되면 정상이다.

1
2
3
4
5
6
(envrust)root@localhost:~/projects/hello_world# cargo build
   Compiling hello_world v0.0.1 (file:///root/projects/hello_world)
    Finished debug [unoptimized + debuginfo] target(s) in 2.33 secs
(envrust)root@localhost:~/projects/hello_world# ./target/debug/hello_world
Hello, world!
(envrust)root@localhost:~/projects/hello_world#
cs



위에서 cargo build 로 프로젝트를 빌드하고 ./target/debug/hello_world 을 실행하였다.

하지만 cargo run 을 통하면 한 번의 명령으로 가능하다.


1
2
3
4
(envrust)root@localhost:~/projects/hello_world# cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_world`
Hello, world!
cs


위의 예제에서는 프로젝트를 리빌드하지는 않았다.

Cargo는 변경사항이 없음을 알고, 단지 바이너라 파일만 실행한 것이다.

만약 소스코드를 수정했다면 Cargo는 실행 전 리빌드하고 실행을 하게 된다.



8. Building for Release


배포준비가 끝났다면  cargo build --release 를 통해서 프로젝트를 최적화할 수 있다.



9. What Is That Cargo.lock?


cargo build 를 실행하면 아래와 같은 Cargo.lock 파일이 생성된다.

1
2
3
4
[root]
name = "hello_world"
version = "0.0.1"
 
cs


어플리케이션간 의존성 추적을 위해 Cargo는 Cargo.lock 파일을 이용한다.

위의 Hello World 프로젝트의 Cargo.lock 파일은 위에서 보시다시피 아무런 의존관계가 없다.



10. Making A New Cargo Project the Easy Way


새로운 프로젝트를 시작할 때마다 위와 같은 과정을 거칠 필요는 없다.

Cargo를 이용하여 새로운 프로젝트를 시작하기 위해서는 아래와 같이 입력한다.

1
2
(envrust)root@localhost:~/projects/hello_world# cargo new hello_world --bin
     Created binary (application) `hello_world` project
cs

Cargo는 이를 통해 아래와 같이 2개의 파일과 하나의 디렉토리를 생성한다.

이상이 새로운 프로젝트를 실행하는데 필요한 전부이다.




그리고 살펴보면 hello_world 디렉토리를 git 저장소로 초기화했음을 알 수 있다.