코틀린(kotlin)에서 조건문, 반복문, 연산자

wooSim·2023년 7월 17일
0

kotlin Study Lab

목록 보기
2/2

다른 언어에서도 기초 문법인 조건문, 반복문, 연산자를 코틀린에서 한번 알아보겠습니다!

📜 조건문


○ if문 예제

kotlin에서의 if 문입니다. 다른 언어의 if 문과 큰 차이가 없어 보입니다.

fun main() {
    fun ifTest(arg: Int) {
        if(arg > 10){
            println("arg > 10")
        }else if(arg > 100){
            println("arg > 100")
        }else{
            println("arg <= 10")
        }
    }
    ifTest(arg = 20)
}
// 결과 
// arg > 10

하지만 kotlin에서 다른 일반적인 if 문과 차이가 있는데 if문이 표현식(expression)이라는 것입니다. expression이라는 것은 결과 값이 발생한다는 의미입니다. 아래 코드를 보면 result 변수에 if문의 결과를 대입하는 것을 볼 수 있습니다.

fun main() {
    fun ifTest(arg: Int) {
        val result = if(arg > 10){
            println("arg > 10")
            arg
        }else if(arg > 100){
            println("arg > 100")
            arg
        }else{
            println("arg <= 10")
            arg
        }
        println("result : $result")
    }
    ifTest(arg = 20)
}
// 결과 
// arg > 10
// result : 20

○ if문을 표현식으로 사용할 때 주의사항

if문을 표현식(expression)으로 사용할 때 참고할 사항이 2가지가 있습니다.

  • 최종 결과값은 if 또는 else if 표현식 내의 마지막 줄에 작성해야 하며, 이 값이 조건에 맞을 때 반환하는 결과 데이터
    • 위 코드에서도 알 수 있듯이 각 블록 내 마지막 줄에 있는 arg 가 결과 값으로 반환되었습니다.
  • else 문이 꼭 있어야 합니다. 생략하면 컴파일에러가 발생합니다.
    • 코틀린 언어의 특징을 생각해보면 당연한 얘기입니다. 변수는 선언과 동시에 초기화가 되어야 하는데 만족되는 조건도 없고 else 문이 없다면 초기화를 할 수 없지 않을까요?

java의 if 문은 표현식이 아니지만 표현식 역할을 하는 연산자가 있습니다. 바로 삼항 연산자 입니다.

int arg = 5;
boolean flag = arg> 10 ? true : false;

kotlin에서는 if문이 표현식 역할을 하기 때문에 따로 삼항 연산자가 존재하지 않습니다.

○ when 예제

kotlin에서는 witch -case 문이 없는 대신 when을 조건문을 제공하며 when 표현식은 더 많은 기능을 제공합니다.


fun main() {
    // 값으로 분기
    val data1 = "hello"
    when(data1){
        "hello" -> println("data1 is hello")
        "world" -> println("data1 is wrold")
        else -> println("data1 is not hello and world")
    }
    // 결과 : data1 is hello

    // 여러 조건을 한꺼번에 분기
    val data2 = 20
    when(data2){
        10, 20  -> println("data2 is 10 or 20")
        30, 40 -> println("data2 is 30 or 40")
    }
    // 결과 : data2 is 10 or 20

    // 범위로 분기
    val data3 = 30
    when(data3){
        in 10..20  -> println("10 <= data3 <= 20")
        in 21..30 -> println("21 <= data3 <= 30")
    }
    // 결과 : 21 <= data3 <= 30
}

위에서 볼 수 있듯이 여러가지 조건으로 분기가 가능합니다.

그리고 if문과 마찬가지로 표현식으로도 활용할 수 있습니다.

val data4 = 2
val result = when(data4){
	1 -> "1"
	2 -> "2"
	else -> {
		"else"
	}
}
println(result)
// 결과 : 2



📜 반복문


○ for 문

java에서의 for문 작성법과 kotlin에서의 for문 작성법에는 차이가 있습니다.

fun main() {
    var sum = 0
    for(i in 1..10){
        sum += i
    }
    println(sum)
}
// 결과 : 55

for 문 조건에 i in 1..10 은 "1부터 10까지 숫자를 1 씩 증가하면서 i에 대입하고 10번 반복하라는 의미 입니다.

for 문에 조건을 다양하게 명시할 수도 있습니다.

  • for(i in 1 until 100){...} : 100은 포함하지 않음
  • for(i in 2..10 step 2){...} : 2씩 증가
  • for(i in 10 downTo 1){...} : 숫자 감소

컬렉션의 요소를 순회하는 방법은 다음과 같습니다.

fun main() {
    val list = listOf<String>("Hello", "World", "!", "?")
    val sb = StringBuffer()
    for (str in list) {
        sb.append(str)
    }
    println(sb)    
}
// 결과 : HelloWorld!?

컬렉션에서 인덱스를 이용하는 방법은 다음과 같습니다.

fun main() {
    val list = listOf<String>("Hello", "World", "!", "?")
    val sb = StringBuffer()
    for (i in list.indices) {
        print("${list[i]} ")
    }
}
// 결과 : Hello World ! ? 

컬렉션에서 인덱스와 값 모두 이용하는 방법은 다음과 같습니다.

fun main() {
    val list = listOf<String>("Hello", "World", "!", "?")
    val sb = StringBuffer()
    for ((index, value) in list.withIndex()) {
        println("$index is $value")
    }
}
//결과 
//0 is Hello
//1 is World
//2 is !
//3 is ?

○ while 문

kotlin에서도 wile과 do-while문은 다른언어와 똑같이 사용할 수 있습니다.

fun main() {
    var x = 0
    var sum = 0
    while(true){
        sum += ++x
        if(x == 10) break
    }
    println(sum)
}
// 결과 : 55

위 코드에서 break 문을 사용하였듯이 continue 문도 똑같이 사용하면 됩니다.


○ label(라벨)

kotlin에서는 label이라는 키워드를 제공하는데 이는 개발자가 특정 위치를 마음대로 이름을 정하고 continue 문이나 break 문에서 지정한 반복문을 벗어나게 할 수 있습니다.

fun main() {
    aaa@ for(i in 1..3){
        for (j in 1..3) {
            if(j > 1) break@aaa
            println("i: $i , j: $j")
        }
    }
}
// 결과 : i: 1 , j: 1



📜 연산자


○ 일치 연산자

연산자의 경우 거의 모든 연산자가 java와 동일합니다. 하지만 그 중 주의할 연산자로 일치 연산자가 있습니다.

  • A == B : A와 B가 같은 값이면 true
  • A != B : A와 B가 다른 값이면 true
  • A === B : A와 B가 같은 객체이면 true
  • A !== B : A와 B가 다른 객체이면 true

언뜻 보면 간단한 얘기일 것 같지만 변수가 nullable하게 선언되었는지, non-null하게 선언되었는지 잘 살펴보아야 합니다.

먼저 일반 객체를 살펴보겠습니다. main 함수 안에 User 클래스를 만들고 비교해보도록 하겠습니다.

fun main() {

    class User{}

    val user1 = User() //non-null
    val user2 = User() //non-null
    val user3 : User? = User() //nullable
    val user4 = user1

    println("일반 객체 비교: ${user1 == user2}, ${user1 === user2}, ${ user1 == user3 }, ${user1 == user4}")
}
// 결과 
// 일반 객체 비교: false, false, false, true

결과에서 알 수 있듯이 일반 객체 비교에서 =====차이가 없습니다. 그냥 객체 비교로 보시면 됩니다.

이제 기초 타입 객체를 살펴보겠습니다.

fun main() {
    val no1 = 1000 //non-null
    val no2 = 1000 //non-null
    val no3 : Int? = 1000 //nullable
    val no4 : Int? = 1000 //nullable

    println("기초 타입 비교: ${no1 == no2}, ${no1 === no2}, ${ no3 == no4 }, ${ no3 === no4 }")
}
// 결과 : 
// 기초 타입 비교: true, true, true, false

먼저 non-null의 비교에서는 ===== 연산자의 결과 차이가 없습니다. 그냥 java에서 기초타입 비교하듯이 값 비교로 보시면 됩니다. 하지만 nullable을 비교할 경우 kotlin에서는 기초 타입일지라도 객체비교를 하게 됩니다. 그렇기 때문에 == 연산자를 사용한 곳에서는 true, === 연산자를 사용한 곳에서는 false를 반환하게 됩니다.

Java에서도 boxing을 들어보셨을 것입니다. kotlin은 java로 변형되어 동작하는데 java에서 int 타입과 Integer 구분되다 보니 이러한 현상이 발생하게 된 것입니다... 간단하게 null을 허용하기 위해 nullable의 경우 null을 허용할 수 있게 한번 더 boxing 했다고 보면 되는 것입니다.

위에 설명이 길었지만 간단하게 정리하자면

  • 일반 객체 : non-null, nullable 상관없이 ==, === 연산자 상관없이 객체 비교를 하면 됩니다.
  • 기초 타입 객체
    • non-null 비교일 경우: ==, ===에 상관없이 값 비교를 하면 됩니다.
    • nullable 비교일 경우: == 연산자를 사용하면 값 비교, === 연산자를 사용할 경우 객체 비교 입니다.
profile
daily study

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

정말 유익한 글이었습니다.

답글 달기