[Android/Kotlin] 8 조건문
조건문에 대해서 알아보자!
- 조건문이란 특정 조건에 따라 실행을 달리하고자 할 때 사용한다.
- ‘제어문’이라고도 하는데, 이는 코드의 흐름을 조건에 따라 바꿀 수 있기 때문이다.
- 제어문에는 크게 조건문에 해당하는 if, when, 그리고 반복문에 해당하는 for, while이 있다.
조건문 if
- 조건문은 어떨 때 사용할까?
- 예로 복권 당첨 프로그램을 들 수 있다.
- 내가 가진 복권 번호가 1, 2, 3, 4, 5, 6이고 이번 주 당첨 번호가 5, 6, 7, 8, 9, 10일 경우 당첨 여부를 조건문 중 하나인 if를 사용해서 다음과 같이 작성할 수 있다.
var myNumbers = "1, 2, 3, 4, 5, 6"
var thisWeekNumbers = "5, 6, 7, 8, 9, 10"
if (myNumbers == thisWeekNumbers){ // if문 시작(해당 조건을 만족하면 if 블록 내의 코드를 수행)
Log.d("Lotto", "당첨되었습니다!")
} // if문 끝
- 위 코드를 보면, 내 번호인 myNumbers와 이번 주 당첨 번호인 thisWeekNumbers가 같은지를 조건문인 if로 비교한 후 같을 경우에는 “당첨되었습니다.”를 출력한다.
- 그러나 조건이 맞지 않을 경우 아무것도 출력하지 않는다.
- 이렇게 특정 코드를 실행하거나 실행하지 않을 때에 조건문을 사용할 수 있다.
- 조건문이란?
- 주어진 조건식의 결괏값이 참인지 거짓인지에 따라 코드를 실행할 것인지 혹은 다른 코드를 실행할 것인지 판단하기 위한 프로그래밍 문법이다.
- Kotlin에서는 if와 when, 두 가지 형태의 조건문을 사용할 수 있다.
if 문을 사용하기 위한 조건
if 문의 조건식에는 비교 연산자(==, <, >)와 논리 연산자(&&, )를 사용한 조건식만 사용 가능하며, 조건식의 결과는 Boolean 타입인 ture(참)와 false(거짓)로 나타낸다. - 비교 연산자(==, <, >)는 보통 두 값을 비교하는 연산자로 다음과 같은 종류가 있다.
연산자 | 의미 | 사용 예 | 결과 |
---|---|---|---|
> | 왼쪽이 크면 true, 작으면 false 반환 | 1 > 2 | false |
< | 왼쪽이 작으면 true, 크면 false 반환 | 1 < 2 | true |
>= | 왼쪽이 크거나 같으면 true, 아니면 false | 1 >= 2 | false |
<= | 왼쪽이 작거나 같으면 true, 아니면 false | 2 <= 2 | true |
== | 2개 항의 값이 같으면 true, 아니면 false | 1 == 2 | false |
!= | 2개 항의 값이 다르면 true, 아니면 false | 1 != 2 | true |
- 비교 연산자는 다음 예제처럼 비교의 결괏값이 true 또는 false 중의 하나인 Boolean 타입으로 반환된다.
var a = 30
var b = 19
var bigger = a > b
Log.d("비교 연산자", "a는 b보다 큽니다.: $bigger") // a는 b보다 큽니다.: true
- 논리 연산자는 주로 비교 연산자로 나타난 결과를 한 번 더 연산하기 위해서 사용된다.
연산자 | 의미 | 사용 예 | 결과 |
---|---|---|---|
&& | 논리곱. 두 항이 모두 true일 때에는 true, 아니면 false | (2 > 1) && (3 < 1) | false |
|| | 논리합. 두 항 중 하나의 항이 true일 때에는 true, 아니면 false | (2 > 1) || (3 < 1) | true |
! | 부정 단항 연산자. true를 false로, false를 true로 바꿈 | ! (2 > 1) | false |
- 논리 연산자의 결괏값도 다음처럼 Boolean 타입으로, true 또는 false 이다.
var a = 30
var b = 19
var c = 37
var bigger = a > b && a > c
Log.d("비교 연산자", "a는 b보다 크고, c보다도 큽니다:$bigger") // a는 b보다 크고, c보다도 큽니다.: false
기본적인 if 문 사용하기
예제를 통해 if 문의 다양한 형식을 살펴보겠다.
다음은 기본적인 if 문의 사용 예이다.
if (조건식) {
// 조건식이 참일 경우 실행되는 코드 영역
}
if 다음에 소괄호 ( )를 작성하고, 소괄호 안에 조건식을 작성한다.
조건식의 결과가 true일 때 처리할 코드를 코드 블록 { } 안에 작성한다.
코드 중간의 여는 중괄호 { 로 시작해 닫는 중괄호 } 를 만날 때까지를 코드 블록(Code Block) 또는 코드 스코프(Code Scope)라고 한다.
다음 예제 코드의 결과를 예측해보자.
var out = 0
var strike = 3
if (strike > 2) {
out = out + 1
}
if 문의 조건식에는 strike가 2보다 크므로 out에 1을 더해준다.
Log를 사용해서 변수 out을 출력하면 ‘1’이 출력된다.
if ~ else 문 사용하기
이번에는 if와 else를 같이 사용한 예이다.
조건식의 결과가 참이면 if 다음에 있는 코드 블록 { } 의 코드가 실행되고, 거짓이면 else 다음에 있는 코드 블록 { } 의 코드가 실행된다.
if (조건식) {
// 조건식이 참일 경우 실행되는 코드 영역
} else {
// 조건식이 거짓일 경우 실행되는 코드 영역
}
- 이번에는 안드로이드 스튜디오에서 직접 코드를 작성해서 Log를 확인해보도록 하겠다.
package net.flow9.thisiskotlin.basicsyntax
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var ball = 4
if (ball > 3) { // ball이 3보다 크면 여기 블록의 코드가 실행됩니다.
Log.d("ControlFlow", "4볼로 출루합니다.")
} else { // 그렇지 않으면 else 다음에 있는 블록의 코드가 실행됩니다.
Log.d("ControlFlow", "타석에서 다음 타구를 기다립니다.")
}
}
}
- 위 코드를 실행하면 로그캣(Logcat)에는 “4볼로 출루합니다.”라는 문구를 확인할 수 있다.
여기서 잠깐!
주석이란?
개발자가 코딩과 관련한 메모를 코드상에 남길 수 있는 것을 주석이라고 한다.
위 코드에서 if 문이 있는 줄의 중간에 //를 사용해서 뒤에 나오는 문장을 주석 처리하였다.
주석 처리된 문장은 컴퓨터가 해석하지 않는다.
주석은 다음과 같이 세 가지로 사용된다.
1) // 한 줄 : 한 줄을 주석 처리할 때 사용하며, 줄의 어느 위치에서 사용해도 해당 줄의 끝까지 주석 처리된다. 2) /* 여러 줄 / : 여러 줄에 걸쳐서 주석 처리할 때 사용하며, /로 시작해서 다음에 나타나는 */를 만날 때까지 모든 글을 주석 처리해서 컴퓨터가 해석하지 않는다. 3) /** 문서화 */ : 자동화 툴을 사용해서 문서화할 정보를 작성할 때는 / 다음에 **가 2개 이다.
주석 사용도 중요하지만, 요즘 추세는 클래스, 함수, 변수의 이름을 점점 더 구체적으로 작성하고 있다.
- 예를 들어 나이를 저장하는 변수를 a라고 작성하고 주석 처리하기보다는 변수명 자체를 age로 작성해서 명시적으로 기술하는 것이 좋다.
// [나쁜 예]
var a = 19 // a: 나이
// [좋은 예]
var age = 19
변수명 뿐만 아니라 함수명, 클래스명 또한 이름만으로 이 함수가 무엇을 하는 함수인지, 이 클래스가 무엇을 위한 클래스인지를 유추할 수 있도록 이름을 구체적으로 기술하는 것이 중요하다!
다음은 로또 번호를 만들어주는 클래스와 함수명을 작성하는 예제이다.
class Lotto {
fun generateNumbers(){
/* 실행 코드 */
}
}
if ~ else if ~ else 문 사용하기
- 다음 구문은 if 문을 반복해서 사용하는 if 문의 예시이다.
if (조건식1) {
// 조건식1의 결과가 참일 경우 실행되는 코드 영역
} else if (조건식 2){
// 조건식1의 결과가 거짓이고, 조건식2의 결과가 참일 경우 실행되는 코드 영역
} else {
// 조건식1과 조건식2의 결과가 모두 거짓일 경우 실행되는 코드 영역
}
이번에는 동일한 조건에서 2개의 if 문으로 작성했을 때와 else if 문을 사용했을 때를 비교해보겠다.
안드로이드 스튜디오에 다음과 같이 코드를 작성한다.
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var a = 1
var b = 2
var c = 3
// 1. if 문 두 번 사용하기
if (a < b) {
Log.d("ControlFlow", "1: a는 b보다 작습니다.")
}
if (a < c) {
Log.d("ControlFlow", "1: a는 c보다 작습니다.")
}
// 2. else if 문 사용하기
if (a < b) {
Log.d("ControlFlow", "2: a는 b보다 작습니다.")
} else if (a < c) {
Log.d("ControlFlow", "2: a는 c보다 작습니다.")
}
}
}
/** [로그캣 출력 내용]
1: a는 b보다 작습니다.
1: a는 c보다 작습니다.
2: a는 b보다 작습니다.
*/
- if 문만 2개 사용할 경우 2개의 if 문이 모두 실행되지만, else if 문을 사용하면 앞의 if 문 조건식을 만족하면 다음에 나오는 else if 문은 실행되지 않는다.
변수에 직접 if 문 사용하기
if 문의 조건식 결과를 변수에 대입할 수 있다.
다음 예제는 a와 b를 비교했을 때 a가 b보다 더 크므로 변수 bigger에 ‘5’를 대입한다.
var a = 5
var b = 3
var bigger = if (a > b) a else b
if 문의 마지막 값을 반환값으로 사용하기
- 위의 코드와 같은데 if 문의 코드 영역이 여러 줄일 경우에도 마지막 줄을 변숫값으로 사용할 수 있다.
var a = 5
var b = 3
var bigger = if (a > b){
var c = 30
a // 마지막 줄의 a 값이 변수 bigger에 저장됩니다.
} else {
b
}
- 안드로이드 스튜디오에서 다음과 같이 코드를 작성해보자!
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var eraOfRyu = 2.32
var eraOfDegrom = 2.43
val era = if (eraOfRyu < eraOfDegrom) {
Log.d("MLB_Result", "2019 류현진이 디그롬을 이겼습니다.")
eraOfRyu
} else {
Log.d("MLB_Result", "2019 디그롬이 류현진을 이겼습니다.")
eraOfDegrom
}
Log.d("MLB_Result", "2019 MLB에서 가장 높은 ERA는 ${era}입니다.")
}
}
/** [로그캣 출력 내용]
2019 류현진이 디그롬을 이겼습니다.
2019 MLB에서 가장 높은 ERA는 2.32입니다.
*/
여기서 잠깐!
문자열 템플릿: 문자열 안에서 수식 사용하기
위 소스 코드의 마지막 줄을 보면 템플릿에 ${ } (달러와 중괄호)를 사용한 것을 확인할 수 있다.
변수가 하나인 경우에는 $변수의 형태로 사용할 수 있지만, 추가적인 연산식이 필요한 경우에는 ${코드 블록} 안에 수식을 입력하는 형태로 사용할 수 있다.
"문자열 $변수 문자열"
"문자열 ${변수 + 1} 문자열"
// 가독성을 높이기 위해 변수 하나만 있을 때도 { }를 사용할 수 있습니다.
"문자열 ${변수} 문자열"
조건문 when
조건문 when을 이해하기 위해서는 먼저 다른 언어의 switch 문을 공부하는 것이 도움이 된다.
switch 문은 if 문의 연산식에서 사용되는 비교 연산자 중에 ==만 사용해서 같은 값인지를 비교하는 조건문이다.
Kotlin을 제외한 거의 모든 컴퓨터 언어에서는 switch라는 이름으로 사용되며 선택문이라고 불리기도 한다.
switch (변수){
case 비교값:
// 변숫값이 비교값과 같다면 이 영역이 실행됩니다.
}
Kotlin의 when 문은 다른 언어와는 다르게 같은 값뿐만 아니라 범위 값도 처리할 수 있고 사용 방법도 더 많다.
Kotlin에서의 when 문은 특정 값을 선택할 수 있는 switch의 사용법에 if 문의 범위 비교 기능이 더해진 if 문의 확장판이라고 생각하면 될 것 같다.
일반적인 형태의 when 사용하기
when 다음에 괄호 ( )를 작성하고 괄호 안에는 주로 비교 대상 파라미터로 사용할 변수명을 입력한다.
if에서처럼 괄호 다음에 중괄호 { }를 사용해서 when 블록을 구분하고 블록 내부에서 비교할 값은 화살표 연산자(Arrow Operator ‘->’)를 사용해서 선택한다.
when (파라미터) {
비교값 -> {
// 변숫값이 비교값과 같다면 이 영역이 실행됩니다.
}
}
위에서 살펴본 switch 문과 비교하면 값을 비교하는 줄 앞의 case가 없어지고 비교값 다음의 콜론이 화살표 연산자(->)로 대체되었다.
여러 개의 값을 하나의 when 문에서 비교할 수도 있다.
when (파라미터) {
비교값1 -> {
// 변숫값이 비교값1과 같다면 이 영역이 실행됩니다.
}
비교값2 -> {
// 변숫값이 비교값2와 같다면 이 영역이 실행됩니다.
}
else -> {
// 변숫값이 앞에서 비교한 것들과 다르면 이 영역이 실행됩니다.
}
}
- 안드로이드 스튜디오에서 아래 코드를 실행하고 로그캣에 출력되는 로그를 확인해보자!
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var now = 10
when (now) {
8 -> {
Log.d("when", "현재 시간은 8시 입니다.")
}
9 -> {
Log.d("when", "현재 시간은 9시 입니다.")
}
else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행 됩니다.
Log.d("when", "현재 시간은 9시가 아닙니다.")
}
}
}
}
/** [로그캣 출력 내용]
현재 시간은 9시가 아닙니다.
*/
콤마로 구분해서 사용하기
- 특정 값을 비교하는데 결과 처리가 동일하다면 콤마(,)로 구분해서 한 번에 비교할 수 있다.
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var now = 9
when (now) {
8, 9 -> {
Log.d("when", "현재 시간은 8시 또는 9시 입니다.")
}
else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행 됩니다.
Log.d("when", "현재 시간은 9시가 아닙니다.")
}
}
}
}
/** [로그캣 출력 내용]
현재 시간은 8시 또는 9시 입니다.
*/
범위 값을 비교하기
in을 사용해서 범위 값을 비교할 수도 있다.
if 문의 비교 연산자 중 <=, >= 과 같은 기능을 구현할 수 있다.
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var ageOfMichael = 19
when (ageOfMichael) {
in 10..19 -> {
Log.d("when", "마이클은 10대 입니다.")
}
!in 10..19 -> {
Log.d("when", "마이클은 10대가 아닙니다.")
}
else -> {
Log.d("when", "마이클의 나이를 알 수 없습니다.")
}
}
}
}
/** [로그캣 출력 내용]
마이클은 10대 입니다.
*/
파라미터 없는 when 사용하기
- when 다음에 오는 괄호를 생략하고 마치 if 문처럼 사용할 수도 있다.
package net.flow9.thisiskotlin.basicsyntax
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var currentTime = 6
when {
currentTime == 5 -> {
Log.d("when", "현재 시간은 5시 입니다.")
}
currentTime > 5 -> {
Log.d("when", "현재 시간은 시가 넘었습니다.")
}
else -> {
Log.d("when", "현재 시간은 5시 이전입니다.")
}
}
}
}
/** [로그캣 출력 내용]
현재 시간은 5시가 넘었습니다.
*/
if 문과 when 문은 언제 사용할까?
“조건문이 2개나 있는데 어떤 것을, 언제 사용할지 모르겠다면?”
구분 방법을 살펴보겠다.
일상적으로 사용하는 데이터 중에서 시간과 관련된 데이터가 있는데 시간 데이터에는 년, 월, 일, 요일, 시간 등의 많은 종류의 데이터가 있다.
이 데이터 중에서 연도 데이터와 요일 데이터를 비교하면 다음과 같은 구체적인 특징이 있다.
연도 데이터
- … 2019, 2020, 2021, 2022, 2023 … : 범위를 한정할 수 없고 개수가 많다.
요일 데이터
- 월, 화, 수, 목, 금, 토, 일: 값을 특정할 수 있고 개수가 7개로 한정되어 있다.
연도 데이터는 2021년과 같이 해당 값을 특정할 수 있지만, 범위가 넓고 미래의 어떤 연도까지 사용한다면 범위 자체를 한정할 수 없다.
- 범위가 넓고 값을 특정할 수 없을 경우에는 if 문을 사용해서 처리하는 것이 바람직하다.
반면, 요일 데이터는 7개로 범위가 제한되고 값도 특정할 수 있다.
- 이럴 경우는 when 문을 사용해주는 것이 더 좋다.
when (요일) {
월 -> 영어 공부를 합니다.
화 -> 자전거 모임이 있습니다.
수 -> 친구를 만납니다.
목 -> 피아노를 칩니다.
금 -> 코딩 공부로 밤을 세웁니다.
토 -> 빨래를 합니다.
else -> 집 청소를 합니다.
}
위 코드와 같이 값을 특정할 수 있고, 개수가 많지 않은 경우에는 when 문을 사용하면 쉽게 잘 읽히는 코드를 작성할 수 있다.
위 코드를 if 문으로 작성하면 아래와 같다.
if (요일 == 월) {
영어 공부를 합니다.
} else if (요일 == 화){
자전거 모임이 있습니다.
} else if (요일 == 수){
친구를 만납니다.
} else if (요일 == 수){
피아노를 칩니다.
} else if (요일 == 목){
코딩 공부로 밤을 세웁니다.
} else if (요일 == 수){
빨래를 합니다.
} else {
집 청소를 합니다.
}
위 코드는 너무 많은 else if 문으로 인해 가독성이 떨어진다는 것을 알았을 것이다!
이처럼 사용하려는 값을 특정할 수 있고 값의 범위가 넓지 않다면 when 문을 사용하는 것이 더 좋은 방법일 수 있다!