2023.11.21 - [백엔드/Rust] - Rust 걸음마 떼기 (1) - Rust 설치 및 실행
책에 나온 예시처럼 다음을 작성하고 실행해본다.
use std::io;
fn main() {
println!("숫자를 맞혀보자");
println!("정답은?");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("입력한 값을 읽지 못했습니다.");
println!("입력한 값: {} ", guess);
}
일단 코드가 자주 보던 애들과 다르게 좀 특이하게생겼다.
let mut guess = String::new();
let foo = 5; // 불변 변수
let mut bar = 5; // 가변 변수 란다.
// String::new는 새로운 String 타입의 인스턴스를 생성해주는것 , 표준라이브러리이며 길이조절이 가능
io::stdin().read_line(&mut guess)
// 여기서는 참조 타입(&)으로 guess 변수를 받아서 복사없이 직접 메모리 접근 가능하다는 의미이다.
// 기본적으로 참조는 변경할수없다고 한다.
// 다만 여기서는 변경 가능한 참조 전달 위해서 &guess가 아닌 &mut guess로 표기했다.
read_line(&mut guess).expect("입력한 값을 읽지 못했습니다.");
// read_line 메서드는 사용자가 입력한 값을 우리가 전달한 문자열에 대입하지만
// io::Result 타입의 값을 리턴하기도 한다.
// Result의 타입은 열거자(enumerations) 이다.
// Result의 열거자의 경우 열것값으로 Ok와 Err이 있다.
println! 자리 지정자를 이용해 값출력
println!("입력한 값: {} ", guess);
let x = 5;
let y = 10;
println!("x = {}, y = {}",x,y);
위와 같이 사용한다.
난수 생성하기 (크레이트)
크레이트란걸 사용해보자
크레이트는 소스파일의 집합이라는 점만 알아두자.
우리가 작업중인 소스도 바이너리 크레이트다.
러스트의 표준 라이브러리는 난수 추출기능을 제공하지 않으나
rand 크레이트를 제공한다.
# Cargo.toml
[dependencies]
rand = "0.6.1"
Cargo.toml의 dependency에 위와같이 추가해보도록 하자.
빌드를 하면 다음과 같이 라이브러리가 포함되어 빌드된다.
그리고 폴더에 보면 cargo.lock 파일이 있는데
카고는 cargo.toml에 명시된 버전의 패키지만 사용한다.
카고는 빌드할때마다 cargo.lock 파일이 존재하는지 확인하고 존재하면 여기에 기록된 버전을 사용한다.
그러면 새로운 버전을 쓰고싶을 땐 어떻게 해야할까?
$ cargo update
명령어를 사용하면 된다.
난수 생성하기 (코드)
use std::io;
use rand::Rng;
fn main() {
println!("숫자를 맞혀보자");
let secret_number = rand::thread_rng().gen_range(1,101);
println!("사용자가 맞춰야할 숫자 : {} ",secret_number);
println!("정답은?");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("입력한 값을 읽지 못했습니다.");
println!("입력한 값: {} ", guess);
}
use rand::Rng 구문을 추가했다. (Rng 트레이트라고 하는데 나중 설명에 나오는듯)
rand::thread_rng함수는 우리가 사용할 난수 생성기를 리턴한다.
gen_range는 1~100까지 난수를 생성한다는것.
난수와 사용자 값 비교하기
출처 입력
새로운 use 구문을 사용해보자
use std::cmp::Ordering
Order 역시 열거자이며 Less, Greater, Equal 값중 하나를 표현한다.
match guess.cmp(&secret_number){
Ordering::Less => println!("입력한 숫자가 작습니다."),
Ordering::Greater => println!("입력한 숫자가 큽니다"),
Ordering::Equal => {
println!("정답.");
break;
}
}
match는 흐름제어 연산자라고 한다.
match 표현식은 여러 개의 가지(arm)으로 구성된다.
각각의 가지는 패턴 그리고 match 표현식의 시작부분에 주어진 값이 이 패턴과 일치할때 실행할 코드로 구성된다.
러스트는 match 표현식에 지정된 값을 읽어 각 가지의 패턴과 차례대로 비교한다.
Ordering의 각 열거자에 대해서 비교 이후 결과를 각각 출력 할 수 있는듯하다.
마치 C/C++의 switch 문과 비슷하게 말이다.
하지만 위의 코드는 실행이 안될텐데
첫번째로는 rust는 비교를 할때 자료형이 완전히 똑같아야한다는 점때문이다.
secret_number는 숫자지만, guess는 현재 string이다. 따라서, 비교가 불가능한 상태다.
그래서
let guess:i32 = match guess.trim().parse(){
Ok(num) => num,
Err(_) => continue,
};
를 추가해야한다.
위에서는
1. i32는 int 32bit을 의미하며 i64도 있다. i32는 i32끼리만 비교가능
2. num은 parse 메서드가 생성 해 넣어 둔 값이다.
3. _ 는 모든 값을 표현한 문자다.
정도만 알아두자.
그래서 loop 이란 반복문을 포함해서 잘 만들어 보면 다음과 같은 코드로 정리할 수 있다.
use std::io;
use rand::Rng;
use std::cmp::Ordering;
fn main() {
println!("숫자를 맞혀보자");
let secret_number = rand::thread_rng().gen_range(1,101);
println!("사용자가 맞춰야할 숫자 : {} ",secret_number);
println!("정답은?");
loop{
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("입력한 값을 읽지 못했습니다.");
let guess:i32 = match guess.trim().parse(){
Ok(num) => num,
Err(_) => continue,
};
println!("입력한 값: {} ", guess);
match guess.cmp(&secret_number){
Ordering::Less => println!("입력한 숫자가 작습니다."),
Ordering::Greater => println!("입력한 숫자가 큽니다"),
Ordering::Equal => {
println!("정답.");
break;
}
}
}
}
continue와 break은 익히 알다시피 반복문에서 쓸수있다.
'백엔드 > Rust' 카테고리의 다른 글
Rust with Flutter Tutorial (4) | 2023.11.21 |
---|---|
Rust 걸음마 떼기 (5) - Rust의 구조체 (2) | 2023.11.21 |
Rust 걸음마 떼기 (4) - 소유권 (러스트의 메모리 관리) (2) | 2023.11.21 |
Rust 걸음마 떼기 (3) - 일반 프로그래밍 개념을 rust에서는 어떻게 다루는가 (1) | 2023.11.21 |
Rust 걸음마 떼기 (1) - Rust 설치 및 실행 (0) | 2023.11.21 |
개발 및 IT 관련 포스팅을 작성 하는 블로그입니다.
IT 기술 및 개인 개발에 대한 내용을 작성하는 블로그입니다. 많은 분들과 소통하며 의견을 나누고 싶습니다.