F.R.I.D.A.Y.

Kotlin: 09 분기 제어-when 본문

DEV/Kotlin

Kotlin: 09 분기 제어-when

F.R.I.D.A.Y. 2020. 4. 2. 23:28
반응형

 분기 제어를 배우는 두 번째 시간입니다. C/C++ 언어[# 이하 C 계열] 등지에서는 switch-case 구문을 이용합니다. 이번 시간에 배울 when 구문은 switch-case 구문에 대응되는 코틀린의 문법이라고 볼 수 있습니다.


when

네이버 사전

 언제를 뜻하는 단어 when은 코틀린 프로그래밍에서는 이전 시간에 배운 if 문 분기처럼 상태에 따라 실행할 코드를 달리하는 분기 제어를 할 때 사용합니다.

구조

 when 문법의 구조는 아래와 같습니다.

when(expression){
    (comparer) -> commands
    [(comparer) -> {
        commands
    }]
    [else -> commands]
}
when(expression)

 어떤 데이터를 기준으로 할지를 정합니다. C 계열의 switch-case 구문과 비교했을 때 아래 부분입니다.

switch(expression){

}
(comparer) -> commands

 기준이 되는 expression과의 데이터 값을 비교합니다. comparer 값이 expression 값과 일치할 경우 화살표(->) 이후의 명령줄(commands)이 실행됩니다. 이때 명령줄은 여러 줄로 표현할 수 있고, 여러 줄로 표현해야 한다면 중괄호로 묶어주어야 합니다.

else -> commands

 comparer 부분에 else 키워드가 들어갔습니다. 이전 if 문법에서 else는 앞선 모든 평가식이 거짓으로 판명되었을 때 실행되도록 구성되었습니다. when 문법에서도 else 키워드는 동일하게 사용됩니다. else가 포함된 when 구문의 comparer 중 어떤 값도 참으로 판명되지 않았다면 else와 이어진 명령줄이 실행됩니다.

사용

 구조를 통해 배운 when의 예제 코드는 다음과 같습니다.

when(bar){
    1 -> println("bar has 1")
    2 -> {
        println("bar has 2")
    }
    else -> println("bar has another thing")
}

 bar[# expression]의 값에 1, 2[# comparer]가 들어있다면 각각 대응되는 명령줄이 실행됩니다. 만일 그 외의 다른 값이 존재한다면 else 구문과 연결된 명령줄이 실행되겠지요.

bar의 값 대응하는 출력
1 bar has 1
2 bar has 2
1, 2를 제외한 나머지 값 bar has another thing
comparer의 확장
범위 연산자 사용하기

 if 구문에서 사용하던 range 연산자(in .. )도 when 구문에서 사용할 수 있습니다.

 범위 연산자를 작성할 땐 범위를 괄호로 묶어서는 안 됩니다. 괄호를 묶게 되면 오류가 발생합니다.

함수 반환 값 사용하기

 함수의 반환 값도 사용할 수 있습니다. sum 함수를 만든다고 생각해봅니다.

fun sum(a:Int, b:Int) = a + b

 bar의 값을 5로, a와 b의 값을 각각 2와 3으로 작성하고 comparer에 sum(a, b)를 넣게 되면 반환 값에 의해 expression과 comparer의 비교가 참으로 평가되고 그에 따라 "bar has 1 or 2" 문자열이 출력됩니다.


다른 언어와 비교하기

 C 계열의 언어와 비교해봅니다.

 C 계열

 C 계열 언어의 switch-case 제한 사항은 다음과 같습니다.

  • comparer 값은 상수로 고정
  • 각 case의 명령이 끝났다면 break를 사용[# 사용하지 않을 경우 이어진 case 구문과 연결된 명령줄 실행]

 그러나 코틀린의 when 구문에서는 comparer 값이 상수로 고정될 필요가 없습니다. 달리 이야기하면 함수의 반환 값 또한 넣을 수 있다는 말입니다.[# 다르게 이야기했을 때, 반환 값을 구하기 위해 해당 함수가 실행됩니다.]

 두 번째, C 계열의 경우에는 case에 대응하는 명령이 끝났을 때, break 키워드를 넣지 않으면 바로 다음 case와 연결된 명령줄이 실행됩니다.

#include <stdio.h>

int main(void){
	int bar;
	scanf("%d", &bar);
	
	switch(bar){
		case 1: printf("bar has 1");
		case 2: printf("bar has 2");
		default:printf("bar has another thing");
	}
	return 0;
}

 위 코드에서 입력을 1로 주게 되면, "bar has 1" 문자열부터 "bar has another thing" 문자열까지 모두 출력됩니다.

1이 입력으로 들어왔을 때, 모든 문자열이 출력되는 모습.

 그러나 코틀린의 경우에는 굳이 break 키워드[# 코틀린에도 동일한 키워드가 존재합니다.]를 입력하지 않아도 됩니다.

코틀린에서 C처럼 사용하기

 break 키워드를 입력하지 않아도 일치하는 case의 명령만 실행되므로 C처럼 when 구문을 이용하기에는 무리가 있습니다.

 

 아니요! 충분히 할 수 있습니다. C 언어에서 case 1과 case 2 가 함께 실행되었던 것처럼 유사하게 코드를 구성할 수 있습니다.

bar의 값이 1이나 2일 때 "bar has 1 or 2" 문자열이 출력된다.

 물론 언어가 다르니 완전히 똑같이 구성할 수는 없지만 컴마 연산자를 통해 expression의 값과 비교하는 대상을 늘릴 수 있습니다.


Extra.

인자 없는 when

 여태는 when 옆에 평가식이 들어있는 when을 공부했습니다. 그러나 평가식이 없는 when도 사용할 수 있습니다.

when{
   (expression) -> commands
}

 기본 구조는 위와 같습니다. 평가식이 존재하는 when과 달리 기존의 comparer 항목 부분이 expression으로 변경되었습니다. 지난 if 구문에서 작성했던 점수를 입력하면 학점을 출력해주는 코드입니다.

fun main(args:Array<String>){
    print("점수 입력: ")
    var score:Int = readLine()!!.toInt()
	
    print("${score}점은 ")
	
    if(score >= 90) print("A")
    else if(score in 80..89) print("B")
    else if(score in 70..79) print("C")
    else if(score in 60..69) print("D")
    else print("F")
	
    println("학점 입니다.")
}

 만일 인자 없는 when으로 작성한다면 아래와 같이 작성할 수 있습니다.

fun main(args:Array<String>){
    print("점수 입력: ")
    var score:Int = readLine()!!.toInt()
	
    print("${score}점은 ")

    when{
        score >= 90 -> print("A")
        score in 80..89 -> print("B")
        score in 70..79 -> print("C")
        score in 60..69 -> print("D")
        else -> print("F")
    }
    println("학점 입니다.")
}

 어떻게 보면 편한 if 구문으로 보이기도 하네요.


다음 시간에는 반복문을 배워보도록 하죠.

Next.

 

Kotlin: 10 반복문-for

만일 100개의 정보를 일일이 확인하는 과정을 직접 손으로 작성해야 한다면, 어떻게 하실 건가요? 오늘은 분기 제어 구문과 함께 프로그램에서 양대 산맥으로 생각할 수 있는 반복문에 대해 알아봅니다. for 구문..

pang2h.tistory.com

# index

728x90
반응형

'DEV > Kotlin' 카테고리의 다른 글

Kotlin: 11 반복문-while, do-while  (0) 2020.04.03
Kotlin: 10 반복문-for  (0) 2020.04.03
Kotlin: 08 분기 제어-if  (0) 2020.04.01
Kotlin: 07 함수  (0) 2020.03.31
Kotlin: 06 세이프콜과 non-null 단정  (0) 2020.03.29
Comments