타나기
타나기 월드
타나기
전체 방문자
오늘
어제
  • 분류 전체보기 (90)
    • ⚙️ Rust (20)
      • 👀 Tutorial (20)
    • 🗿 Embedded (11)
      • 🐧 OS for ARM (11)
    • 💻 Study (37)
      • 🧩 알고리즘 (37)
    • 🏄🏽‍♂️ Life (21)
      • 🍚 타나구루망 (20)
      • 💡 Light (1)

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
타나기

타나기 월드

⚙️ Rust/👀 Tutorial

[Rust / 튜토리얼] 7. Rust의 제어문

2022. 5. 16. 23:49

제어문

컴퓨터 일을 하다 보면, 결국 모든 프로그래밍 언어는 제어문의 조합이라는 생각이 든다.
프로그래밍이란 컴퓨터를 제어하는 활동이기 때문인 걸까?
대부분의 언어에서 제어문은 기본으로 알아야 프로그래밍을 할 수 있으니 Rust의 제어문에 대해서 알아 보도록 하자.

if 표현식

if 표현식은 코드가 조건에 따라 분기할 수 있도록 한다.
분기라고 하니 어려워 보이지만, 조건문이 참일경우 괄호 안에 있는 코드를 실행 하라는 의미이다.

if 는 else if 와 else와 함께 쓰일 수 있다.
else if는 앞서 실행한 if의 조건이 만족하지 않을 경우 다음 조건을 제시해 코드를 실행하고, else는 if와 else if모두 조건을 만족하지 못하면 제일 마지막에 실행 된다.
따라서 if -> else if -> else 순서로 코드가 호출된다.

여기까지는 C언어와 비슷하다고 느낄 수 있는데, 몇몇은 좀 다르다.
첫번째로, 소괄호 ()를 쓰지 않는다.
두번째로, 조건문이 반드시 bool형태여야 한다는 것이다.
세번째로, 변수를 할당 할 때 조건문을 활용할 수 있다.
아래의 코드를 보자

fn main() {
let num = 3;
if num < 3 {
        println!("1. number is {}!", num);
    } else if num == 3 {
        println!("2. number is {}!", num);
    } else {
        println!("3. number is {}!", num);
    }
}

코드는 당연히 "2. number is 3"를 출력한다.
여기서 일부러 오류를 발생시키기 위해 약간의 수정을 해 보자.

fn main() {
    let num = 3;

    if num {
        println!("number is {}!", num);
    } else {
        println!("number is {}!", num);
    }
}

if문의 조건이 bool형태가 아니므로 아래와 같은 오류가 발생한다.

   Compiling test_exam v0.1.0 (C:\Folder\source\rust\test_exam)
error[E0308]: mismatched types
 --> src\main.rs:4:8
  |
4 |     if num {
  |        ^^^ expected `bool`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `test_exam` due to previous error

오류문은 친절하게 bool형이 아닌 integer형이 if문에 조건문으로 들어갔다고 알려준다.

let 구문에서 if 사용하기

조건문을 활용해 let 구문을 사용할 수 있다.
이는 조건에 따라 변수를 할당 할 때 선언과 동시에 할당할 수 있어서 유용하다.
아래의 코드를 봐보자.

fn main() {
    let intellect: String = "Babo".to_string() ;
    let food = if intellect.contains("Babo") {
        "Candy"
    } else {
        "None"
    };

    println!("Eat {}", food);
}

못난놈 떡하나 더준다는 코드인데, 실행하면 "Eat Candy"를 출력한다.
이렇게 상황에 따라 다른 값을 할당 할 수 있다.
그런데 만약 할당해 주는 두개의 타입이 다르면 오류를 뱉게 된다.

fn main() {
    let intelige: String = "Babo".to_string() ;
    let food = if intelige.contains("Babo") {
        "Candy"
    } else {
        5
    };

    println!("Eat {}", food);
}
error[E0308]: `if` and `else` have incompatible types
 --> src\main.rs:7:9
  |
4 |       let food = if intelige.contains("Babo") {
  |  ________________-
5 | |         "Candy"
  | |         ------- expected because of this
6 | |     } else {
7 | |         5
  | |         ^ expected `&str`, found integer
8 | |     };
  | |_____- `if` and `else` have incompatible types

For more information about this error, try `rustc --explain E0308`.
error: could not compile `test_exam` due to previous error
터미널 프로세스 "C:\Users\zingr\.cargo\bin\cargo.exe 'run'"이(가) 종료되었습니다(종료 코드: 101).

친절히 알려주는 오류 메시지에서 if와 else의 타입이 다르다고 한다.
서로 다른 타입까지 할당이 가능하다면 좋을텐데 아쉽다.
하긴 그럴 때 사용하라고 Python이 있나보다.
쉽고 빠르고 간단하게 구현하고 싶으면 Python을 사용하자.

반복문

컴퓨터 언어를 처음 배울때 반복문을 통해 '*' 문자를 출력 하던게 기억이 난다.
뱅글뱅글 도는 반복문을 이용해 나무 같은 것을 그렸던 것 같다.
반복문은 무언가를 순서대로 출력 할 때처럼 특정 로직을 반복할 때 사용한다.
Rust가 제공하는 반복문은 아래의 3가지 이다

  • loop
  • while
  • for

loop

loop는 흔히들 말하는 무한루프를 떠올리면 될 것 같다.
C언어에서는 while(1) {..,} 과 같이 작성해 무한루프를 만들었지만 Rust에서는 loop를 이용해 쉽게 사용할 수 있다.

fn main() { 
loop { 
println!("again!"); 
} 
}

위의 코드는 "again!" 을 프로그램 강제 종료 할 때까지 출력한다.
강제종료 없이 빠져나오고 싶다면 break 키워드를 사용 하도록 하자.

while

위에선 break를 명시적으로 적어 줬다면, while문의 경우 조건이 거짓이 되면 break를 호출한다.
따라서 loop , if, break를 잘 조합한다면 while문을 직접 만들어 사용할 수 도있다.
하지만 그런 비효율 적인 짓은 하지 말자.

아래의 코드는 카운트 다운을 3부터 하는 코드이다.

fn main() {
    let mut num = 3;

    while (num > 0) {
        num -= 1;
        println!("count down! {}", num + 1);
    }
}

결과

    Finished dev [unoptimized + debuginfo] target(s) in 0.42s
     Running `target\debug\test_exam.exe`
count down! 3
count down! 2
count down! 1

for문

for문은 위의 두개의 반복문과는 성격이 약간 다르다.
단순 반복이 아닌 배열이나 콜렉션 같은 집합의 각 요소들을 탐색할 때 사용한다.
아래의 예시를 통해 배열을 어떻게 탐색하는지 알아보자.

fn main() {
    let array = [0, 1, 2, 3, 4, 5];

    for num in array {
        println!("Number is {}", num);
    }
}

결과

   Compiling test_exam v0.1.0 (C:\Folder\source\rust\test_exam)
    Finished dev [unoptimized + debuginfo] target(s) in 1.04s
     Running `target\debug\test_exam.exe`
Number is 0
Number is 1
Number is 2
Number is 3
Number is 4
Number is 5

위에서 보다시피 첫번째 요소부터 마지막 요소까지 탐색하는 것을 알 수 있다.
이걸 while문으로 구현 하려고 했다면 index와 같은 변수를 따로 선언하고 array[index] 와같이 직접적으로 배열에 접근 해야 했을 것이다.
하지만 이렇게 직접적으로 접근하는 경우는 배열의 길이를 반드시 알고 있어야 하고, 범위를 벗어난 index로 접근하게 되면 오류를 발생할 가능성이 크니, for문을 잘 활용 하도록 하자.

for문은 또한 특정 range를 탐색할 때도 자주 사용된다.

fn main() {
    for num in 1..6 {
        println!("Number is {}", num);
    }
}
   Compiling test_exam v0.1.0 (C:\Folder\source\rust\test_exam)
    Finished dev [unoptimized + debuginfo] target(s) in 0.55s
     Running `target\debug\test_exam.exe`
Number is 1
Number is 2
Number is 3
Number is 4

여기서 주의할 점은 1..6 에서 6은 범위에 포함하지 않는다는 점이다.
역순으로 5~1 까지 출력하고 싶으면 아래처럼 작성하면 된다.

fn main() {
    for num in (1..6).rev() {
        println!("Number is {}", num);
    }
}
Number is 5
Number is 4
Number is 3
Number is 2
Number is 1

마무리

이로써 언어의 기본이 되는 변수의 선언과 제어문을 알게 되었다.
다음 글에서는 Rust하면 가장 먼저 떠오르는 그것, 소유권에 대해서 써보도록 하겠다.

저작자표시 (새창열림)

'⚙️ Rust > 👀 Tutorial' 카테고리의 다른 글

[Rust / 튜토리얼] 9. 러스트의 참조자와 빌림  (0) 2022.05.23
[Rust / 튜토리얼] 8. 러스트의 소유권  (0) 2022.05.20
[Rust / 튜토리얼] 6. 함수의 동작  (0) 2022.05.11
[Rust / 튜토리얼] 5. Rust 데이터 타입  (0) 2022.05.10
[Rust / 튜토리얼] 4. 변수와 가변성  (0) 2022.05.06
    '⚙️ Rust/👀 Tutorial' 카테고리의 다른 글
    • [Rust / 튜토리얼] 9. 러스트의 참조자와 빌림
    • [Rust / 튜토리얼] 8. 러스트의 소유권
    • [Rust / 튜토리얼] 6. 함수의 동작
    • [Rust / 튜토리얼] 5. Rust 데이터 타입
    타나기
    타나기
    #include<all>

    티스토리툴바