체인의정석

Rust 기본 학습과 설치 및 기본 guessing game 예제 본문

블록체인/Rust

Rust 기본 학습과 설치 및 기본 guessing game 예제

체인의정석 2023. 1. 13. 16:07
728x90
반응형

컨트렉트 개발자로서 이제 Rust도 학습해보고자 한다. 이에 따라서 기본적인 학습을 진행하였다.

 

mac 환경에서 설치

 

공식 도큐먼트 사용

https://doc.rust-lang.org/book/ch01-01-installation.html

 

Installation - The Rust Programming Language

The first step is to install Rust. We’ll download Rust through rustup, a command line tool for managing Rust versions and associated tools. You’ll need an internet connection for the download. Note: If you prefer not to use rustup for some reason, plea

doc.rust-lang.org

그러나 에러가 발생하였다.

➜ ~ curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh 

curl: (4) A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision.

그 결과 해당 블로그를 보고 설치하기로 하였다.

https://happygrammer.github.io/rust/install/

 

Rust 설치하기

 

happygrammer.github.io

 

1. rust up이라는 프로그램으로 설치 진행

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

To get started you may need to restart your current shell.

그리고 버전 체크를 해줘야 하는데 쉘을 껐다 키라고 한다.

➜ ~ rustc --version
rustc 1.66.1 (90743e729 2023-01-10)

껐다 키고 버전을 체크해보니 잘 나온것을 볼 수 있었다.

 

2. cargo 사용

https://doc.rust-lang.org/book/ch01-03-hello-cargo.html

 

Hello, Cargo! - The Rust Programming Language

Cargo is Rust’s build system and package manager. Most Rustaceans use this tool to manage their Rust projects because Cargo handles a lot of tasks for you, such as building your code, downloading the libraries your code depends on, and building those lib

doc.rust-lang.org

일단 cargo는 마치 노드의 npm 같은 느낌으로 생각하였다. 여기에 기본 예제가 다 있다.

cargo build // 디버깅 까지 해줌
cargo run // cargo build + 실행까지 해줌
cargo check // 컴파일 되는지 체크해줌

Let’s recap what we’ve learned so far about Cargo:

  • We can create a project using cargo new.
  • We can build a project using cargo build.
  • We can build and run a project in one step using cargo run.
  • We can build a project without producing a binary to check for errors using cargo check.
  • Instead of saving the result of the build in the same directory as our code, Cargo stores it in the target/debug directory.

cargo new로 프로젝트 생성 cargo build로 디버깅 및 빌드 진행 cargo run으로 한번에 프로젝트 실행시켜버리기

그리고 cargo check를 통해서 바이너리 생성 전에 컴파일 가능한지 에러를 체크해 줄 수 있고

target/debug 위치에 build 결과가 자동으로 저장되게 된다.

 

3. vs code 세팅

rust-analyzer를 사용한다.

 

4. quessing game

https://doc.rust-lang.org/book/ch02-00-guessing-game-tutorial.html

 

Programming a Guessing Game - The Rust Programming Language

Let’s jump into Rust by working through a hands-on project together! This chapter introduces you to a few common Rust concepts by showing you how to use them in a real program. You’ll learn about let, match, methods, associated functions, external crat

doc.rust-lang.org

기본 예제중 하나이다.

➜ rust cargo new guessing_game
     Created binary (application) `guessing_game` package
➜ rust cd guessing_game       
➜ guessing_game (master) ✗

먼저 cargo new 를 통해 프로젝트를 생성한다.

➜ guessing_game (master) ✗ cargo run              
   Compiling guessing_game v0.1.0 (/Users/chohk/Desktop/git/rust/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 0.66s
     Running `target/debug/guessing_game`
Hello, world!

 

기본적으로 작성된 프로그램은 헬로월드 이다.

 

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

이걸 guessing game으로 바꿔본다.

이중 input output은

io::stdin()Stdin

이걸 사용해서 구현한다.

그리고 변수의 선언은

    let mut guess = String::new();

요런식으로 해서 유저의 input을 할당해 준다고 한다.

이때 mut는 가변적인 변수임을 의미한다.

let apples = 5; // immutable
let mut bananas = 5; // mutable

추측하는 숫자는 가변값이기 때문에 mut를 넣어준다고 보면 된다.

 

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

그 다음 이부분을 보자.

이 부분에서 read_line을 통해서 guess값을 입력받아오면 

요런식으로 결과 값이 나오게 된다. 이 부분은 결과 값으로 오류가 나올 경우에 해당 부분을 처리해 주는 부분이다.

이런식으로 예외 처리를 안해줄 경우 컴파일 과정에서 에러가 나며 expect를 통해 readline을 잘 통과하고 결과 값이 넘어와서 예외 부분까지 잘 처리되는 경우 프로그램이 잘 돌아가게 된다.

 

마지막  prinlt ln의 {} 이 부분인데 이것은 마치 

자바스크립트의

`${}`

요것과 비슷한거 같다.

#![allow(unused)]
fn main() {
let x = 5;
let y = 10;

println!("x = {x} and y + 2 = {}", y + 2);
}

그래서 글자안에 변수를 넣어주게 될 경우에는 해당 변수가 그대로 프린트 되게 된다.

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

실행 결과는 아래와 같다.

➜ guessing_game (master) ✗ cargo run  
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/guessing_game`
Guess the number!
Please input your guess.
3
You guessed: 3

4. guessing game 에 랜덤 기능 추가시키기

 

Cargo.toml 여기는 마치 package.json과 같은 느낌이다.

[package]
name = "guessing_game"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.8.5"

rand 디펜던시를 넣어주고 난 후에 cargo build (마치 npm inatll)을 해주고 나면 설치가 된다.

 

➜ guessing_game (master) ✗ cargo build
    Blocking waiting for file lock on package cache
    Updating crates.io index
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on build directory
   Compiling libc v0.2.139
   Compiling cfg-if v1.0.0
   Compiling ppv-lite86 v0.2.17
   Compiling getrandom v0.2.8
   Compiling rand_core v0.6.4
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.5
   Compiling guessing_game v0.1.0 (/Users/chohk/Desktop/git/rust/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 42.41s

자 이제 랜덤 로직을 넣어주겠다.

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

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

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

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

use rand는 마치 import를 해오는 부분인것 같다.

다시 가져와서 랜덤을 1~100사이에서 하나 가져오는 부분을 만들고 cargo run을 실행시키면 다음과 같이 실행이 된다.

➜ guessing_game (master) ✗ cargo run  
   Compiling guessing_game v0.1.0 (/Users/chohk/Desktop/git/rust/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 0.39s
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 2
Please input your guess.
4
You guessed: 4

이제 마지막 코드를 보기 전에 몇개 문구를 추가시키겠다.

 

먼저 Ordering은 enum으로 Less, Greater, Eqaul이 있다.

또한 cmp는 비교를 해주는 함수이다.

 

 match guess.cmp(&secret_number)

요런식으로 해주면 guess와 secret_number를 비교해주는 것이 된다.

 

또한 match의 경우 match에 주어진 값들이 arm 안의 값들과 일치하는지 여부를 보고 판단한다.

arm이 러스트 표지 모델의 꽂게의 손같이 생겨서 arm이라고 표현하는 것 같은데

guess.cmp 에 대한 결과 값이 Ordering 형태로 나오기 때문에 거기에 따른 일치하는 값을 리턴해 주는 것 같다.

 

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

또한 문자와 숫자를 비교할 때 이런식으로 할 시 

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

trim은 공백을 제거 시켜주며 , parse는 string을 다른 자료형으로 바꾸어 준다.

이에 따라서 실질적인 비교가 가능하게 된다.

 

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

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

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

    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!("You win!");
                break;
            }
        }
    }
}

다시 전체 코드를 봐보면 이제 직관적이게 읽히게 된다.

직접 해보니 자바스크립트 보다 , 타입스크립트 보다 훨씬 더 검사를 타이트하게 하는 느낌이다.

728x90
반응형
Comments