conditional expression

Hunter_Joe·2023년 8월 4일
0

Rust 기초

목록 보기
3/8
post-thumbnail

conditional expression

  • 조건은 기본적으로 결정을 내릴 수 있는 권한 부여
  • 표현의 상태를 확인하고 그에 따라 행동

if

  • if에는 조건이 필요
  • 조건이true로 평가되면 코드 블록 실행

syntax

if condition {
	statement1;
    statement2;
    .
    .
    statementN;
}

example

fn main() {
      let learn_language = "Rust";
      
      if learn_language == "Rust" { 
         println!("You are learning Rust language!");
      }
}

1. if... else

  • if... else구문에서iffalse로 평가되면 else블록내의 명령문 실행

syntax

if condtion { 
	statement; //true 실행문
} else {
	statement; //false 실행문 
}

example

fn main() {
    let learn_language = "Rust";
    
    if learn_language == "Rust" { 
        println!("You are learning Rust language!");
    }
    else {
      println!("You are learning some other language!");
    } 
}

2. if... else if... else

  • 확인할 조건이 여러개인 경우에 사용됨

syntax

if condtion {
	statement; 
} else if condtion {
	statement;
} else {
	statement;
}

example

fn main() 
      let learn_language="Rust";
      
      if learn_language == "Rust" { 
         println!("You are learning Rust language!");
      }
      else if learn_language == "Java" { 
         println!("You are learning Java language!");
      }
      else {
         println!("You are learning some other language!");
      } 
}

nested if expression

  • if표현식 본문 내부에 다른 if표현식이 존재하는 것

syntax

if condtion {
	if condition {
    	statement; 
    }
}

note

  • 이중 if문은 AND식으로 작성 할 수도 있음
    if condtion1 && condition2 {
    statement;
    }
    : 이 경우는 두 번째 if문이 첫 번째 if문안에 있는 유일한 경우에만 해당

example

fn main() {
    let learn_language1 = "Rust";
    let learn_language2 = "Java";

    if learn_language1 == "Rust" {  // inner if statement
        if learn_language2 == "Java"{
              println!("You are learning Rust and Java language!");
        }
    }
    else {
      println!("You are learning some other language!");
    } 
}

shorthand if

  • if... else를 축약형으로 적을 수 있음
let x = if(condition) {statement} else { statement};

note

  • 위 축약형은 C, C++과 같은 언어의 삼항 연산자와 유사

example

fn main() {
    let learn_language = "Rust";

    let res= if learn_language == "Rust" {"You are learning Rust language!"} else {"You are learning some other language!"};
    println!("{}", res);
}

note

  • expression은 statement와 다르게 value를 반환할 수 있음.
  • semicolon은 모든 expression을 statement로 바꾼다.
  • 값을 버리고 unit()(빈 튜플)을 반환.
fn main() {
    let x = "Rust";

    let y: bool = if x == "Rust" { true } else { false };

    // let z: bool = if x == "Rust" { true; } else { false; };

    println!("x:{}", x);
    println!("y:{}", y);

}

note

  • 위 코드 6행의 주석을 제거하면
    표현식을 명령문으로 변환 하므로 값을 반환하지 않아 오류 발생

if let

  • if let는 패턴 일치를 허용하는 조건식
  • 코드 블록은 조건의 패턴이 scrutinee expression의 패턴과 일치하는 경우 실행

note

  • 패턴의 일치 : define pattern이 scrutinee expression과 같은 수의 값을 가짐을 의미
    matching of pattern : it means that the defined pattern has the same number of values as that of the scrutinee expression.

example

case 1 (패턴 일치)

fn main() {
    // define a scrutinee expression    
    let course = ("Rust", "beginner","course");
    // pattern matches with the scrutinee expression
    if let ("Rust", "beginner","course") = course {
        println!("Wrote all values in pattern to be matched with the scrutinee expression");
    } else {
        // do not execute this block
        println!("Value unmatched");
    }
}
fn main() {
    // define a scrutinee expression    
    let course = ("Rust", "beginner","course");
    // pattern matches with the scrutinee expression
    if let ("Rust", "beginner", c) = course {
        println!("Wrote first two values in pattern to be matched with the scrutinee expression : {}", c);
    } 
    else {
        // do not execute this block
        println!("Value unmatched");
    }
}
---------------------------------------
* 첫 번째 or 두 번째 값이 일치하면 세 번째 값을 추측할 수 있음
fn main() {
    // define a scrutinee expression     
    let course = ("Rust", "beginner","course");
    // pattern matches with the scrutinee expression
    if let ("Rust", c, d) = course {
        println!("Wrote one value in pattern to be matched with the scrutinee expression.Guessed values: {}, {}",c,d);
    } else {
        // do not execute this block
        println!("Value unmatched");
    }
}
---------------------------------------
첫 번째 값이 일치하면 다른 두 값을 추측할 수 있음 

case 2 (패턴 불일치)

fn main() {
    // define a scrutinee expression     
    let course = ("Rust", "beginner");
  
    if let ("Java", c) = course {
        println!("Course is {}", c);
    } else {
        // execute this block
        println!("Value unmatched");
    }
}

case 3 (패턴이 '_'로 대체될 때)

fn main() {
    // no pattern is define
    if let _ = 10 {
        println!("irrefutable if-let pattern is always executed");
    }
}
  • 위 예시에서는 패턴이 정의되지 않음.
    오히려 _의 경우 if let 블록 내의 명령문이 실행됨

note

  • warning 경고 생성됨

match expression

  • 일치 표현식 현재 value가 value목록에 있는 value에 해당하는지에 대해 확인한다
  • 일치 표현식은 C, C++와 같은 언어의 switch 문과 유사
  • if/else구성과 비교할 때 더 간결한 코드를 제공
  • match keyword 사용

method 1

  • match 블록 내에서 result 변수에 값을 할당하지 않으려는 경우

example

fn main() {
    // define a variable 
    let x = 5;
    // define match expression
    match x {
        1 => println!("Java"),
        2 => println!("Python"),
        3 => println!("C++"),
        4 => println!("C#"),
        5 => println!("Rust"),
        6 => println!("Kotlin"),
        _ => println!("Some other value"),
    };
}
------------------------------------------
*console 
rust 

method 2

  • match 블록 내에서 result 변수에 값을 할당하려는 경우

example

fn main(){
   // define a variable
   let course = "Rust";
   // return value of match expression in a variable
   let found_course = match course {
      "Rust" => "Rust",
      "Java" => "Java",
      "C++" => "C Plus Plus",
      "C#" => "C Sharp",
      _ => "Unknown Language"
   };
   println!("Course name : {}",found_course);
}
------------------------------------------
*console 
Course name : Rust

3가지 조건문 비교

if statement

  • It is desired to test the truthiness of an expression
  • There is a single affirmative test
  • There is a need to evaluate different expressions for each branch
  • It can test expressions based on ranges of values or conditions

match statement

  • It is desired to compare multiple possible conditions of an expression
  • The values belong to the same domain
  • It can test expressions based on values only, i.e., condition cannot take ranges

if let statement

  • There is a pattern in the condition and it is to be matched with the scrutinee expression

expression vs statement

1. expression

  • 표현식은 value로 평가되는 코드 조각
    ex) number, string, boolean 등은 모두 표현식

  • 연산자를 사용하여 값을 계산하거나 변수의 값을 사용하는 것도 표현식에 해당

  • rust에서 대부분의 statement도 표현식임 즉, 대부분의 코드 블록 또는 코드 조각들은 값을 반환
    이러한 특성 때문에 "expression-based language" 라고 불림

2. statement

  • statement는 프로그램에서 어떤 작업을 수행하지만 값을 반환하지는 않음
    ex) 할당문, 함수 정의, 제어문(if, for, while 등) 등이 있음

  • rust에서 문장은 보통 semicolon;으로 끝남

  • ; : 문장의 종료를 의미 이로 인해 해당 문장은 값을 반환하지 않고 비어있는 unit()을 반환하게 됨

exapmple 1

fn main() {
    let a = 10; // 할당문, a 변수에 10을 할당하는 문장
    let b = 20; // 할당문, b 변수에 20을 할당하는 문장
    let sum = a + b; // a와 b의 합을 계산하여 sum에 할당하는 문장
}

위 코드에서 첫 두줄은 ;으로 끝나므로 값이 없는 unit값 ()반환

example 2

fn main() {
    let learn_language = "Rust";

    let res= if learn_language == "Rust" {"You are learning Rust language!"} else {"You are learning some other language!"};
    println!("{}", res);
}

이제 처음 제시한 코드를 보면, if learn_language == "Rust" {"You are learning Rust language!"} else {"You are learning some other language!"} 부분이 표현식입니다. 이 표현식은 조건에 따라 "You are learning Rust language!" 또는 "You are learning some other language!"라는 두 가지 문자열 중 하나를 반환합니다.

하지만, 이 표현식을 let res = ...;로 변수에 할당하면 더 이상 표현식이 아니라 문장이 됩니다. 변수에 값을 할당하는 문장이기 때문에 세미콜론을 사용하여 문장으로 처리되고, 반환값은 유닛값 ()이 됩니다. 그래서 코드에서 res 변수의 값은 유닛값 ()이 아니라 "You are learning Rust language!" 또는 "You are learning some other language!"가 됩니다.

간단하게 말하면, let res = if ...의 경우 if-else 표현식의 결과를 res 변수에 할당하여 저장하므로, 값을 반환받을 수 있습니다. 하지만 let res = ...;의 경우 세미콜론으로 끝나면서 값을 버리고 유닛값 ()을 반환하게 됩니다.

unit

유닛 값(())은 Rust에서 사용되는 특별한 타입으로, 빈 튜플을 나타내는 값입니다. 튜플은 여러 요소를 그룹화하는 데 사용되는 데이터 타입인데, 유닛 값은 아무런 요소도 가지지 않는 빈 튜플을 의미합니다.

유닛 값은 Rust에서 주로 함수나 표현식의 반환 타입이 없을 때 사용됩니다. 예를 들어, 함수가 어떤 값을 반환하지 않을 때 해당 함수의 반환 타입은 ()가 됩니다.

간단한 예시를 통해 살펴보겠습니다:

fn greet() -> () {
    println!("Hello!");
    // 반환 타입이 ()이므로, 아무 값도 반환하지 않는다.
}

fn main() {
    let result = greet();
    println!("{:?}", result); // 결과: ()
}

greet() 함수는 반환 타입이 ()이기 때문에 아무런 값을 반환하지 않고, main() 함수에서 호출해도 반환값은 빈 튜플 ()입니다. 유닛 값은 크게 중요한 역할을 하지는 않지만, Rust에서 함수나 표현식의 반환 타입이 필요하고 아무 것도 반환하지 않을 때 사용되는 특별한 타입입니다.

profile
hunting season

0개의 댓글