rust, guessing_game

lsh235·2023년 6월 6일
0

rust

목록 보기
3/7

게임 시작부분

src:

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);
}

variable:

러스트에서 변수는 기본적으로 불변.
let foo = 5; // 불변
let mut bar = 5; // 가변
let mut guess = String::new(); // 가변

io:

use std::io;
https://doc.rust-lang.org/std/prelude/index.html
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
read_line은 사용자로부터 입력 받음.
&는 코드의 여러 부분에서 데이터를 여러 번 메모리로 복사하지 않고 접근하기 위한 방법을 제공하는 참조자.
참조자도 변수처럼 기본적으로 불변이기 때문에 mut가 있어야함.(const ref 개념?)

read_line에서는 하나의 값을 돌려주는데 이때 돌려주는 값은 io::Result
Result의 variants는 Ok와 Err가 있고 expect 메소드를 가지고 있습니다.
Err일 경우 expect 메소드는 프로그램이 작동을 멈추게 하고 expect에 인자로 넘겼던 메세지를 출력하도록 합니다.

io::stdin().read_line(&mut guess);
다음과 같이 expect를 호출하지 않는다면 컴파일은 되지만 경고가 나타납니다.

변경자(placeholder):

println!("You guessed: {}", guess); // c++ fmt

비밀번호 생성

package:

rand

cargo.toml:

[dependencies]
rand = "0.3.14" // 추가

Cargo.lock:

임의적으로 dependencies에 대해서 업데이트 하지 않는 이상
자동으로 재현가능한 빌드를 생성.

cargo update:

Cargo.toml 에 여러분이 명시한 요구사항에 맞는 최신 버전을 확인합니다. 만약 이 버전들로 문제가 없다면 Cargo는 해당 버전을 Cargo.lock 에 기록합니다.

src:

extern crate rand;

use std::io;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_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);
}

extern crate rand:

extern crate rand;을 추가하여 러스트에게 우리가 외부에 의존하는 크레이트가 있음을 알립니다. 이 라인은 use rand으로도 표기할 수 있으며 이제 우리는 rand::를 앞에 붙여 rand내의 모든 것을 호출할 수 있습니다.

비밀번호와 추리값을 비교하기

src:

use std::{io, cmp::Ordering};

use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_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);

    match guess.cmp(&secret_number) {
        Ordering::Less      => println!("Too small!"),
        Ordering::Greater   => println!("Too big!"),
        Ordering::Equal     => println!("Too win!"),
    }
}

but not compile

why? guess is string type and secret_number is int32 type.
so we are change guess type to int.

shadowing:

let guess: u32 = guess.trim().parse()
    .expect("Please type a number!");

guess_str과 guess처럼 고유의 변수명을 만들도록 강요하는 대신 guess를 재사용 가능하도록 합니다.

trim:

trim is delete blank from start and end.
why delete blank to change type?
read line을 종료하려면 enter를 입력해야하는데 enter에는 \n이 포함되기 때문입니다.
trim은 이런 \n을 제거해줍니다.

parse:

문자열의 parse 메소드는 문자열을 숫자형으로 파싱합니다.
let guess: u32와 같이 정확한 타입을 명시해야 합니다.
또한 parse 메소드의 호출은 에러가 발생하기 쉽습니다. 만약 A👍%과 같은 문자열이 포함되어 있다면 정수로 바꿀 방법이 없기때문에 expect가 필요합니다.

반복문을 이용하여 여러 번의 추리 허용

src:

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

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

        let mut guess = String::new();

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

        let guess: u32 = guess.trim().parse()
            .expect("Please type a number!");

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

        match guess.cmp(&secret_number) {
            Ordering::Less    => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal   => println!("You win!"),
        }
    }
}

정답 이후에 종료하기

src:

        match guess.cmp(&secret_number) {
            Ordering::Less      => println!("Too small!"),
            Ordering::Greater   => println!("Too big!"),
            Ordering::Equal     => {
                println!("Too win!");
                break;
            }
        }

잘못된 입력값 처리하기

src:

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

완성코드

src:

use std::{io, cmp::Ordering};

use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

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

        let mut guess = String::new();

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

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

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

        match guess.cmp(&secret_number) {
            Ordering::Less      => println!("Too small!"),
            Ordering::Greater   => println!("Too big!"),
            Ordering::Equal     => {
                println!("Too win!");
                break;
            }
        }
    }
}

0개의 댓글