체인의정석

Rust 기본 프로그래밍 컨셉 (Control Flow - 조건문, 반복문) 본문

블록체인/Rust

Rust 기본 프로그래밍 컨셉 (Control Flow - 조건문, 반복문)

체인의정석 2023. 1. 16. 17:48
728x90
반응형

Control Flow

조건이 참일때 코드를 반복적으로 돌리는 행위는 가장 기본적인 프로그래밍 기법으로서 러스트에서는 if와 loop가 가장 대표적이다.

 

IF 표현

if 표현은 조건이 맞으면 코드가 돌아가고 안맞으면 안돌아가는 기초적인 프로그래밍이다.

branches라는 경로를 만들고 한번 진행해보도록 하겠다.

➜ functions (master) ✗ cargo new branches 
     Created binary (application) `branches` package

기본적인 if 문은 다음과 같이 만들면 된다.

fn main() {
    let number = 3;

    if number < 5 {
        println!("condition was true");
    } else {
        println!("condition was false");
    }
}

여기에 대한 결과 값은 다음과 같이 나온다.

➜ branches (master) ✗ cargo run    
   Compiling branches v0.1.0 (/Users/chohk/Desktop/git/rust/branches)
    Finished dev [unoptimized + debuginfo] target(s) in 1.36s
     Running `target/debug/branches`
condition was true

매우 일반적인 반복문과 유사하다. 하지만 만약 조건문에 bool 값이 들어가는 경우는 자바스크립트와 차이가 발생하게 되는데 자바스크립트에서는 그냥 조건문에서 bool 형태를 알아서 찾아와 줬었지만 러스트에서는 bool 자료형을 꼭 지정해 주어야 한다고 한다.

fn main() {
    let number = 3;

    if number {
        println!("number was three");
    }
}

이런식으로 넣는다면 number가 자바스크립트에서는 존재한다면 bool이 true가 되어서 통과 되겠지만 러스트에서는

➜ branches (master) ✗ cargo run
   Compiling branches v0.1.0 (/Users/chohk/Desktop/git/rust/branches)
error[E0308]: mismatched types
 --> src/main.rs:4:8
  |
4 |     if number {
  |        ^^^^^^ expected `bool`, found integer

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

에러가 발생하게 된다.

 

따라서 bool 비교는 bool로 선언된 값을 사용해야 한다.

fn main() {
    let number = 3;

    if number == 3 {
        println!("number was three");
    }
}

이런식으로 해서 직접 비교를 해주거나

 

fn main() {
    let number = 3;

    if number != 0 {
        println!("number was something other than zero");
    }
}

이런식으로 숫자를 지정해서 사용해 주어야 한다.

 

else if 문 넣기

fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}

위와 같이 해주면 된다.

true가 되면 이후 값은 체크하지 않는데 자바스크립트와 같은것 같다.

하지만 문서에는 if 문이 2개 이상이면 match를 사용하라고 써져 있다.

let statment안에 if 사용하기

if는 expression이기 때문에 let statement에서 사용이 가능하다.

fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {number}");
}

이런 식으로 statement안에 if 문을 사용할 수 있다.

물론 조건의 타입이 비교하는 타입과 다를 경우 

fn main() {
    let condition = true;

    let number = if condition { 5 } else { "six" };

    println!("The value of number is: {number}");
}

요런 경우 에러가 나게 된다.

 

Loop을 사용하여 반복하기

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

이렇게 loop를 쓰면 터미널을 나가기 전까지 반복된다.

fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {result}");
}

loop을 빠져나가려면 위와 같이 break를 해주어야 한다.

만약 loop문이 중첩된 케이스라면 break와 continue를 내부적으로 사용하면 된다.

또한 선택적으로 loop label을 지정한 후 break와 continue를 사용할 수 있는데 이런 식으로 지정하면 아래와 같이 

' 하나로 loop문을 지정한 후에 2중첩된 break를 사용할 때 더 명시해서 안전하게 사용할 수 있다.

fn main() {
    let mut count = 0;
    'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;

        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up;
            }
            remaining -= 1;
        }

        count += 1;
    }
    println!("End count = {count}");
}

loopl label을 현재 counting_up으로 지정해 놓았기 때문에 count 2에서 loop 문 전체가 끝나게 된다.

loop문이 현재 2개가 있는데

 

첫번째로는 remaining이 9가 되면 break가 되어서 loop문 밖으로 나갔다가 count가 하나 더 증가해서 다시 내부의 loop문으로 가고 2번 반복한 후에 countingup이 break되게 되면 그 순간 루프문 바깥의 print가 실행되게 된다.

 

이런식으로 2중 loop의 경우에는 loop label을 활용하는 것이 더 명시적인 방법인것 같다. 저 코드를 루프 라벨 없이 하려니 break를 밖으로 빼주어야 해서 코드도 가시성이 안좋았으며 순서 또한 정확히 똑같이 하기는 어려웠다. 이건 꼭 기억해두고 컨트렉트 짤때도 종종 써야겠다.

 

While을 사용하여 조건이 붙은 Loops 써보기

fn main() {
    let mut number = 3;

    while number != 0 {
        println!("{number}!");

        number -= 1;
    }

    println!("LIFTOFF!!!");
}

 

loop, if, else, break를 섞어서 사용한다면 위의 코드 보다 더 복잡한 문구가 되지만 while을 사용하면 위처럼 간단하게 사용이 가능하다.

 

for를 사용한 looping

fn main() {
    let a = [10, 20, 30, 40, 50];
    let mut index = 0;

    while index < 5 {
        println!("the value is: {}", a[index]);

        index += 1;
    }
}

이런식의 반복문을

fn main() {
    let a = [10, 20, 30, 40, 50];

    for element in a {
        println!("the value is: {element}");
    }
}

요런식으로 for 문을 써서 사용할 수 있다.

자바스크립트와 동일한거 같다.

 

그리고 for 문에다가 함수를 더 넣어서 여러 기능들을 사용할 수 있기 때문에 for in은 숙지하면 좋다고 한다.

fn main() {
    for number in (1..4).rev() {
        println!("{number}!");
    }
    println!("LIFTOFF!!!");
}

요런식의 식을 실행하면

➜ branches (master) ✗ cargo run
   Compiling branches v0.1.0 (/Users/chohk/Desktop/git/rust/branches)
    Finished dev [unoptimized + debuginfo] target(s) in 0.87s
     Running `target/debug/branches`
3!
2!
1!
LIFTOFF!!!

요런식으로 함수가 적용된다고 한다.

 

예시만 봐도 엄청 많이 쓸거 같은 느낌이 든다.

 

 

728x90
반응형
Comments