# Rust 스터디 1회차
- [Rust 레퍼런스 번역 문서](https://rinthel.github.io/rust-lang-book-ko/) 스터디
## 들어가기 앞서
- 어려운 메모리 관리, 데이터 표현, 그리고 동시성에 대한 저수준의 디테일을 다루는 “시스템 레벨” 관련 일을 --> 길을 잃지 않도록 다양한 지원을 제공
- 러스트 프로그래밍은 권한 분산에 관한 것
- 메모리 관리, 동시성에 대한 저수준을 다루는 시스템 레벨에서 실수하지 않도록 도와준다.
- 읽어본 결과, 번역이 매끄럽지 못한 부분도 있는 듯 했음
## 소개
- 누구에게 유용한가?
### 개발자 팀
- 버그 추적보다 프로그램 로직 자체에 집중할 수 있음
- 그러므로 리소스를 효율적으로 사용할 수 있다.
- 유용한 툴이 제공된다
- Cargo (패키지 매니저)
- Rustfmt (코딩 스타일 툴)
- Rust Language Serve (자동완성, 인라인 에러메시지)
### 속도와 안정성을 소중하게 생각하는 사람
- 생산성이 좋다(개발 및 동작 속도와 안정성 확보)
### 이 책을 이용하는 방법
관련해서 3장 보고 2장의 소스를 나름대로 수정해보는건 어떨까요?
## 설치하기
- rustup을 통해 설치 https://www.rust-lang.org/en-US/install.html
- 버전 정보 확인
```cmd=
> rustc --version
```
## Hello, World!
### 코드
```rust=
fn main() {
println!("Hello, world!");
}
```
### 실행하기
```cmd=
> rustc main.rs
> ./main
Hello, world!
```
### main 함수
- main 함수는 특별하다.
- 첫번째로 실행되는 함수
- C언어와 비슷하니 금방 와닿을 듯
- rustfmt라는 자동 포맷팅 도구가 개발된 것 같음
- 검색해보니 이미 다 나와 있는 것 같음
- 러스트는 탭이 아닌 4개의 들여쓰기를 사용
- `println!`은 러스트 매크로
- 각각의 라인은 `;`으로 끝남
### 컴파일과 실행은 개별적인 단계입니다
- Windows에서 컴파일하면 pdb 파일(심볼 파일)이 같이 생성됨
- main.exe
- main.pdb
- main.rs
```cmd=
> rustc main.rs
> .\main.exe
```
## Hello, Cargo!
- 빌드 시스템 및 패키지 매니저
```cmd=
> cargo --version
```
- 프로젝트 생성
```cmd=
> cargo new hello_cargo --bin
> cd hello_cargo
```
- --bin 옵션은 실행파일 프로젝트
- `cargo new`를 통해 생성한 Cargo.toml 파일
```toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
[dependencies]
```
- `[package]` 이후 문장은 패키지 환경설정
- `[dependencies]` 이후는 프로젝트 의존성
- crate 를 사용해 코드 패키지를 추가할 수 있다.
### Cargo 프로젝트를 빌드하고 실행하기
```console
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
- `cargo build` 시에 target/debug 폴더 하위에 빌드 결과물이 생김
```console
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
```
- `cargo run` 빌드와 실행을 한번에 함
```
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
- cargo check
- 컴파일이 되는지 확인 용도
- 실행파일을 원치 않을때(실행파일을 생성하지 않으므로 빠름)
- Cargo를 사용하면 어떤 OS를 사용하든 커맨드가 동일하다!
### 관례로서의 Cargo
- 프로그램이 복잡할 수록 rustc보다 Cargo 사용이 좋다 (dependencies를 이용한 패키지 관리의 편리함)
## 추리 게임
### 새로운 프로젝트를 준비하기
```
cargo new guessing_game --bin
```
### 추리값을 처리하기
```rust=
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);
}
```
```rust
use std::io;
```
use 키워드
- 사용자 입력을 받기 위해 `io`라이브러리를 사용해야함.
let 키워드
- 변수 선언(ex: let guess )
- rust의 변수는 기본이 불변
mut 키워드
- mut 키워드를 써야 변경 가능 (ex: let mut var)
연관 함수
- "::" == 정적 메소드
```rust
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
```
- read_line 함수는 표준 입력에 입력될때마다 문자열에 추가하므로 값을 저장할 문자열을 가변(&mut)으로 받는다
### Result 타입으로 잠재된 실패 다루기
- Result 타입
- 열거형(enumerations)
- 정해진 값들을 가질 수 있음 -> 열거형의 variants
- 성공시 Ok, 실패시 Err
- expect
- 프로그램 작동을 멈춤(exception)
- 지정한 문자열을 출력
- expect를 사용하지 않을 경우 경고
- 개발자가 예외가 발생할 수 있는 상황을 인지하게함
### println! 변경자(placeholder)를 이용한 값 출력
```rust
println!("x = {} and y = {}", x, y);
```
- C++ 20에 추가된 [std::format](https://en.cppreference.com/w/cpp/utility/format/format) 과 유사
### 비밀번호를 생성하기
- Crate는 러스트에서 패키지를 말함
#### 패키지 추가
```toml
[dependencies]
rand = "0.3.14"
```
- 기본적으로 cargo 버전은 SemVer 규칙을 따름
- Cargo는 Crates.io 데이터 복제본인 레지스트리에서 모든것을 가져온다
### Cargo.lock
- 누구라도 같은 산출물이 나오도록 보장하는 메타 정보가 기록되는 파일
- 명시적으로 업그레이드하지 않은 이상 Cargo.lock 정보를 기반으로 해당 버전을 사용
### 크레이트를 새로운 버전으로 업그레이드하기
```
$ cargo update
Updating registry `https://github.com/rust-lang/crates.io-index`
Updating rand v0.3.14 -> v0.3.15
```
#### Crate 버전 업데이트
- toml 파일에서 버전 수정
```toml
[dependencies]
rand = "0.4.0"
```
### 임의의 숫자 생성하기
```rust=
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);
}
```
- `cargo doc --open` 명령어로 사용중인 패키지가 제공하는 문서를 브라우저에 표시해줌
### 비밀번호와 추리값을 비교하기
```rust=
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);
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!("You win!"),
}
}
```
```rust
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
```
- C/C++ 등의 switch-case-break 문 사용 방식과 유사한데, 매우 심플한 듯
- match 표현식은 arm으로 이루어짐.(arm: 하나의 패턴)
### Shadowing
- 이전 값을 가리는 것을 허용
```rust=
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!");
```
- Shadowing의 유용함에 대한 의문..?
- 더이상 불필요한 변수를 Shadowing으로 소멸시키는 것과 관련 있지 않을까?
- 효율적인 성능과 메모리 관리 관점?
### 반복문을 이용하여 여러 번의 추리 허용
#### loop 키워드
- 무한 루프를 제공
- break 문으로 탈출
### 잘못된 입력값 처리하기
```rust=
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
```
#### 완성된 코드
```rust=
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);
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;
}
}
}
}
```
## 회고
- 이지한: 첫번째 시간인데 나름 잘 진행된 것 같습니다.
- 허신: mut, & 과 같은 것들을 명확하게 하는 것이 인상적이었습니다.
- 정연집: crate가 편해보입니다.
- 유병조: 코틀린이랑 비슷한 시기에 나와서 그런지 유사점이 있는거 같습니다(match, 불변 변수 권장), 함수형 지원이 어떤지 궁금하네요
- 이명수: 용어가 좀 낯설지만 재미지네요 ㅎㅎ
- 김기덕: 새로운 것들을 공부하는게 좋았습니다.
- 이재현: 기본 변수가 불변이라는게 좀 특이하다고 생각했습니다.