갈루아의 반서재

사용자가 정답을 추측하는 Guessing game 을 만들어보자.


1. 아래와 같이 새로운 프로젝트(guessing_game)을 생성한다. cargo new 명령을 통해서 새로운 cargo 프로젝트를 명명하고, 바이너리임을 나타내는 --bin 플래그를 붙인다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bourne@vikander MINGW64 ~/Evariste/workspace (master)
$ cd rust-projects
 
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects (master)
$ cargo new guessing_game --bin
     Created binary (application) `guessing_game` project
 
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects (master)
$ ls -al
total 8
drwxr-xr-1 bourne 197121 0 10월 17 19:11 ./
drwxr-xr-1 bourne 197121 0 10월 17 18:44 ../
drwxr-xr-1 bourne 197121 0 10월 17 19:11 guessing_game/
drwxr-xr-1 bourne 197121 0 10월 17 18:53 hello_world/
 
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects (master)
$ cd guessing_game
 
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects/guessing_game (master)
$
 
cs


2. Cargo.html 파일의 내용을 확인한다. 만약 내용이 틀리다면 수정하도록 한다.

1
2
3
4
5
6
7
[package]
name = "guessing_game"
version = "0.1.0"
authors = ["Alex Jin Choi <alexjinchoi@gmail.com>"]
 
[dependencies]
 
cs


3. src/main.rs 파일을 확인한다.

1
2
3
4
fn main() {
    println!("Hello, world!");
}
 
cs


4. 컴파일링 후 실행해본다.

1
2
3
4
5
6
7
8
9
10
11
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects/guessing_game (master                   )
$ cargo build
   Compiling guessing_game v0.1.0 (file:///C:/Users/vikander/Evariste/workspace/rust-projects/guessing_game)
    Finished debug [unoptimized + debuginfo] target(s) in 0.40 secs
 
bourne@vikander MINGW64 ~/Evariste/workspace/rust-projects/guessing_game (master)
$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target\debug\guessing_game.exe`
Hello, world!
 
cs


5. 이제 위에서 생성한 main.rs 을 아래와 같이 수정한 후 실행해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use std::io;
 
fn main() {
    println!("Guess the number!");
 
    println!("Please input your guess.");
 
    let mut guess = String::new();
 
    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");
 
    println!("You guessed: {}", guess);
}
cs


Line 1 :

use std::io;

표준 라이브러리에서 io 라이브러리가 필요하므로, use std::io; 를 통해서 io 관련한 것들을 불러온다.


Line 3 :

fn main() {

fn 새로운 함수 선언

( ) 특별한 인수는 없음

{ 함수의 body 시작을 나타냄


Line 4, Line 6 :

    println!("Guess the number!");

    println!("Please input your guess.");

println! 은 앞서 살펴봤듯이 문자열을 출력해주는 매크로이다.


Line 8 :

  let mut guess = String::new();

let 위 문장이 변수를 선언하는 let statement 임을 나타낸다.

mut 기본적으로 immutable 이므로 mut 키워드를 통해 mutable(변경가능한_) 변수임을 알려줘야한다.

String 변수의 유형이 표준라이브러리에서 제공하는 문자열 타입임을 알려준다.

:: 특정 타입에 연계된 함수임을 나타낸다. 즉, 여기서는 문자열에 연계된 함수라는 것이다(static method).

new() 함수의 이름



Line 10~11 :

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

io::stdin() 앞에서 언급한 std::io 관련 함수를 호출한다. 만약 Line 1 에서 use std::io; 를 입력하지 않았다면,  io::stdin() 가 아니라 std::io::stdin() 라고 입력해야 한다. 이 함수는 표준 입력에 관한 것을 다룬다. 더욱 자세한 내용은 std::io::Stdin을 참고하면 된다.


.read_line(&mut guess)

.read_line() 사용자의 인풋을 가져오는 메서드이다. 메서드는 연관 함수로서 특정한 타입의 인스턴트에서 사용가능하다. 여기서는 &mut guess 라는 인수를 넘긴다.

앞서 guess 라는 변수를 mutable 하다고 선언했지만, read_line 은 문자열을 인수로 가져오지 않고, &mut String 을 인수로 가져온다.

Rust는 레퍼런스라고 하는 기능을 가지고 있는데, 복사를 줄이기 위해 하나의 데이터에 복수의 참조를 허용한다. 레퍼런스는 복잡한 기능으로 당장은 알 필요가 없다. 일단 알아야할 것은 let binding 과 마찬가지로 레퍼런스의 기본값도 immutable 하다는 사실이다. 따라서 &guess 가 아니라 &mut guess 라고 해야한다.

그러면 왜 read_line() 은 mutable reference 를 문자열에 필요로 하는가? read_line() 의 역할은 사용자의 입력을 표준입력으로 가져와 문자열로 집어넣는 것이다. 따라서 문자열을 인수로 필요로 하고, 입력을 처리하기 위해 mutable 해야한다.


  .expect("Failed to read line");

expect() io::Result 를 반환한다. Rust는 표준 라이브러리에 Result 라는 이름이 붙은 다수의 타입을 가지고 있다. Result 타입의 목적은 에러 처리 정보를 인코딩하는 것이다. 다른 타입과 마찬가지로 Result 타입 역시 특정 메서드를 가지고 있다. 이 경우에서는 io::Result expect() 메서드를 가지고 있다. 이 라인을 생략하면 Result 값을 사용하지 않았다는 경고를 발생한다. 즉, 발생가능한 에러를 처리하지 않았다는 것이다.


1
2
3
4
5
6
7
8
   Compiling guessing_game v0.1.0 (file:///C:/Users/vikander/git/rust-projects/rust-projects/guessing_game)
warning: unused result which must be used, #[warn(unused_must_use)] on by default
  --> src\main.rs:17:5
   |
17 |     io::stdin().read_line(&mut guess);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
cs


    println!("You guessed: {}", guess);
}

이제 마지막 라인이다. 이 라인은 입력한 문자열을 출력해주는 부분이다. { } 부분에 guess 변수를 인수로 입력받는다. 만약 복수의 { } 가 존재한다면 복수의 인수를 입력받을 수 있다. 여기까지 작성한 후 실행해보면 아래와 같은 결과를 얻을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
bourne@vikander MINGW64 ~/git/rust-projects/rust-projects/guessing_game (master)
$ cargo run
   Compiling guessing_game v0.1.0 (file:///C:/Users/vikander/git/rust-projects/rust-projects/guessing_game)
    Finished debug [unoptimized + debuginfo] target(s) in 0.24 secs
     Running `target\debug\guessing_game.exe`
Guess the number!
Please input your guess.
8
You guessed: 8
 
 
 
cs