Chap.2 gussing-game
해당 학습 자료를 정리 및 수행한 기록입니다.
이번 장은 몇몇 일반적인 Rust 개념과 활용 방법을 배울 수 있습니다.
let
match
- 메소드,
- 연관함수(assiciated functions),
- 외부 크레이트(external crates)
이번 장에서는 여러분이 직접 기초적인 내용을 실습합니다.
우리는 고전적인 입문자용 프로그래밍 문제인 추리 게임을 구현해 보려 합니다.
- 먼저 프로그램은 1~100 사이의 임의의 정수를 생성합니다.
- 다음으로 플레이어가 프로그램에 추리한 정수를 입력합니다.
- 프로그램은 입력받은 추리값이 정답보다 높거나 낮은지를 알려줍니다.
- 추리값이 정답이라면 축하 메세지를 보여주고 종료됩니다.
값을 변수에 저장하기
// 사용자 입력을 받고 결과값을 표시하기 위해서는 io (input/output) 라이브러리를 스코프로 가져와야 합니다.
// io 라이브러리는 std 라고 불리는 표준 라이브러리에 있습니다.
use std::io;
fn main() {
// print
println!("Guess the number!");
println!("Please input your guess.");
// mut string 변수 선언
let mut guess = String::new();
// input 받는 코드
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
// 출력
println!("You guessed: {}", guess);
}
러스트에서 변수는 기본적으로 불변입니다.
let foo = 5; // 불변
let mut bar = 5; // 가변
-
String::new
의 결과값인 새로운String
인스턴스가 묶이는 대상이 됩니다. -
String
은 표준 라이브러리에서 제공하는 확장 가능한(growable) UTF-8 인코딩의 문자열 타입입니다. -
::new
에 있는::
는new
가String
타입의 연관 함수 (associated function) 임을 나타냅니다. -
연관함수는 하나의 타입을 위한 함수이며, 이 경우에는 하나의
String
인스턴스가 아니라String
타입을 위한 함수입니다. -
몇몇 언어에서는 이것을 정적 메소드 (static method) 라고 부릅니다.
-
new
함수는 새로운 빈String
을 생성합니다.new
함수는 새로운 값을 생성하기 위한 일반적인 이름이므로 많은 타입에서 찾 아볼 수 있습니다.
요약하자면 let mut guess = String::new();
라인은 새로운 빈 String
인스턴스와 연결된 가변변수를 생성합니다.
우리는 io
의 연관함수인 stdin
을 호출합니다:
io::stdin() .read_line(&mut guess)
stdin
함수는 터미널의 표준 입력의 핸들(handle)을 나타내는 타입인 std::io::Stdin
의 인스턴스를 돌려줍니다.
코드의 다음 부분인 .read_line(&mut guess)
는 사용자로부터 입력을 받기 위해 표준 입력 핸들에서 read_line
메소드를 호출합니다. 또한 read_line
에 &mut guess
를 인자로 하나 넘깁니다.
&
는 코드의 여러 부분에서 데이터를 여러 번 메모리로 복사하지 않고 접근하기 위한 방법을 제공하는 참조자 임을 나타냅니다.- 참조자는 복잡한 특성으로서 러스트의 큰 이점 중 하나가 참조자를 사용함으로써 얻는 안전성과 용이성입니다.
- 지금 당장은 참조자가 변수처럼 기본적으로 불변임을 알기만 하면 됩니다. 따라서 가변으로 바꾸기 위해
&guess
가 아니라&mut guess
로 작성해야 합니다.
Result
타입으로 잠재된 실패 다루기
read_line
은 우리가 인자로 넘긴 문자열에 사용자가 입력을 저장할 뿐 아니라 하나의 값을 돌려 줍니다.- 여기서 돌려준 값은
io::Result
입니다. - 러스트는 표준 라이브러리에 여러 종류의
Result
타입을 가지고 있습니다. - 제네릭
Result
이나io:Result
가 그 예시입니다
Result
의 variants는 Ok
와 Err
입니다.
Ok
는 처리가 성공했음을 나타내며 내부적으로 성공적으로 생성된 결과를 가지고 있습니다.
Err
는 처리가 실패했음을 나타내고 그 이유에 대한 정보를 가지고 있습니다.
io::Result
가 Ok
값이라면 expect
는 Ok
가 가지고 있는 결과값을 돌려주어 사용할 수 있도록 합니다. 이 경우 결과값은 사용자가 표준 입력으로 입력했던 바이트의 개수입니다.
만약 expect
를 호출하지 않는다면 컴파일은 되지만 경고가 나타납니다.
println!
변경자(placeholder)를 이용한 값 출력
println!("You guessed: {}", guess);
비밀번호를 생성하기
러스트는 아직 표준 라이브러리에 임의의 값을 생성하는 기능이 없습니다.
하지만 러스트 팀에서는 rand
크레이트를 제공합니다.
크레이트(Crate)를 사용하여 더 많은 기능 가져오기
- 크레이트는 러스트 코드의 묶음(package)임을 기억하세요.
- 우리가 만들고 있는 프로젝트는 실행이 가능한 binary crate 입니다.
rand
crate는 다른 프로그램에서 사용되기 위한 용도인 library crate 입니다.
Cargo에서 외부 크레이트의 활용 예시
rand
를 사용하는 코드를 작성하기 전에 Cargo.toml 을 수정rand
크레이트를 의존 리스트에 추가
[dependencies]
rand = "0.8.5"
우리는 외부 의존성을 가지게 되었고, Cargo는 Crates.io 데이터의 복사본인 레지스트리(registry) 에서 모든 것들을 가져옵니다.
Crates.io는 러스트 생태계의 개발자들이 다른 사람들도 이용할 수 있도록 러스트 오픈소스를 공개하는 곳입니다.
레지스트리를 업데이트하면 Cargo는 [dependencies]
절을 확인하고 아직 여러분이 가지고 있지 않은 것들을 다운 받습니다.
이 경우 우리는 rand
만 의존한다고 명시했지만 rand
는 libc
에 의존하기 때문에 libc
도 다운 받습니다.
러스트는 이것들을 다운받은 후 컴파일하여 의존성이 해결된 프로젝트를 컴파일합니다.
크레이트를 새로운 버전으로 업그레이드하기
Cargo는 update
명령어를 제공합니다.
이것은 Cargo.lock 파일을 무시하고 Cargo.toml 에 여러분이 명시한 요구사항에 맞는 최신 버전을 확인합니다.
확인이 되었다면Cargo는 해당 버전을 Cargo.lock 에 기록합니다.