고딩왕 코범석

코드 제어 본문

Language & Framework/Kotlin

코드 제어

고딩왕 코범석 2022. 7. 30. 21:57
반응형

Index

  1. 코틀린에서 제어문을 다루는 방법
    1. if문
    2. Expression과 Statement
    3. switch와 when
  2. 코틀린에서 반복문을 다루는 방법
    1. for-each문
    2. for문
    3. Progression과 Range
    4. while문
  3. 코틀린에서 예외를 다루는 방법
    1. try catch finally
    2. Checked Exception과 Unckecked Exception
    3. try with resource
  4. 코틀린에서 함수를 다루는 방법
    1. 함수 선언 문법
    2. default Parameter
    3. named Argument
    4. 같은 타입의 여러 파라미터 받기 (가변인자)

코틀린에서 제어문을 다루는 방법

if문

fun validateScoreIsNotNegative(score: Int) {
        if (score < 0) {
            throw IllegalArgumentException()
        }
    }

코틀린의 함수 반환 타입에서 void를 Unit으로 표현하고 이는 생략이 가능하다. 이 외에는 자바와 차이가 없다. 즉, if는 자바와 같다.

Expression과 Statement

자바에서 if-else는 Statement지만 코틀린에서는 Expression이다.

  • Statement
    • 프로그램의 문장, 하나의 값으로 도출되지 않는다.
  • Expression
    • 하나의 값으로 도출되는 문장
// 자바
    // 30 + 40은 하나의 결과가 나온다. 따라서 Expression도 되고 Statement도 된다.
    int score = 30 + 40;
    
    // 자바에서 if-else는 Statement다. 
    // 즉, 자바에서는 if-else를 하나의 값으로 취급하지 않아서 이와 같은 문장으로 코딩할 경우 
    // 컴파일 예외가 발생한다.
    String grade = if (score >= 50) {
        return "P";
    } else {
        return "F";
    }
    
    // 3항 연산자는 Statement면서 Expression
    String grade = score >= 50 ? "P" : "F"
// 코틀린은 if-else를 하나의 Expression으로 취급해서 if-else문 앞에 return을
    // 붙여 바로 반환할 수 있다.
    // 즉, 3항 연산자가 없다.
    fun getPassOrFail(score: Int) = 
        return if (score >= 50) { 
            "P"
        } else { 
            "F"
        }

switch와 when

when의 형태는 다음과 같다.

fun getGradeWithSwitch(score: Int): String {
        // 코틀린에서 switch 문이 사라짐
        return when(score) {
            in 90..99 -> "A"
            in 80..89 -> "B"
        in 70..79 -> "C"
            else -> "D"
        }
    }
    
    fun startsWithA(obj: Any): Boolean {
        return when(obj) {
            // 스마트 캐스트
            is String -> obj.startsWith("A")
            else -> false
        }
    }
    
    fun judgeNumber(number: Int) {
        when(number) {
            // 여러 개 조건
            1, 0, -1 -> println("1, 0, -1이 맞습니다.")
            else -> println("1, 0, -1이 아닙니다.")
        }
    }
    
    fun judgeNubmer2(score: Int) {
        when {
            number == 0 -> println("주어진 숫자는 0 입니다.")
            number %2 == 0 -> println("주어진 숫자는 짝수입니다.")
            else -> println("주어진 숫자는 홀수입니다.")
        }
    }
  • ‘→’ 를 기준으로 왼쪽은 조건부, 오른쪽은 구문이라 하는데 조건의 경우 어떠한 Expression이라도 다 다들어갈 수 있다.
  • 조건부에서는 여러 개의 조건을 동시에 검사할 수 있다.
  • Enum과 Sealed Class와 함께 사용할 때 아주 유용하다.

위로

코틀린에서 반복문을 다루는 방법

for-each문

val numbers = listOf(1L, 2L, 3L)
    // numbers에는 Iterable을 구현한 타입이라면 모두 들어갈 수 있다.
    for (number in numbers) {
        println(number)
    }

for문

// ..은 코틀린에서 범위를 나타내는 연산자
    for (i in 1..3) {
        println(i) // 1, 2, 3
    }
    
    // i가 감소하는 반복문
    for (i in 3 downTo 1) {
        println(i) // 3, 2, 1
    }
    
    for (i in 1..5 step 2) {
        println(i) // 1, 3, 5
    }

Progression과 Range

  • ..
    • 범위를 만들어 내는 연산자
    • 이는 rangeTo()를 의미하고 IntProgression을 반환해준다.
    • 이는 등차수열을 만들어주는 코드다.
    • ex)
      • 3 downTo 1: 시작값 3, 끝값 1, 공차가 -1인 등차수열
      • 1..5 step 2: 시작값 1, 끝값 5, 공차가 2인 등차수열
    • downTo, step도 함수다. (infix)

while문

자바와 완전 똑같다. do-while도 마찬가지

위로

코틀린에서 예외를 다루는 방법

try catch finally

타입이 뒤에 오고 new 키워드를 사용하지 않는 것을 제외하고 자바와 동일

// try catch도 Expression으로 간주
    fun parseIntOrNull(str: String): Int? {
        return try {
            str.toInt()
        } catch(e: NumberFormatException) {
            null
        }
    }

Checked Exception과 Unchecked Exception

throws 문이 없다. 코틀린에서는 ChekcedUnckecked 예외를 구분하지 않는다. 모두 Unchecked로 취급한다.

fun readFile() {
        val currentFile = File(".")
        val file = File(currentFile.absolutePath + "/a.txt")
        val reader = BufferedReader(FileReader(file))
        println(reader.readLine())
        reader.close()
    }

try with resource

코틀린은 try with resource 구문이 없다. use 확장 함수를 통해 사용한 리소스를 자동으로 close 해준다.

fun readFile() {
        // use 확장 함수 사용을 통해 리소스 자동 해제
        BufferedReader(FileReader(file)).use { reader -> 
            pritnln(reader.readLine())
        }
    }
@InlineOnly
    @RequireKotlin("1.2", versionKind = RequireKotlinVersionKind.COMPILER_VERSION, message = "Requires newer compiler version to be inlined correctly.")
    public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
        contract {
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        }
        var exception: Throwable? = null
        try {
            return block(this)
        } catch (e: Throwable) {
            exception = e
            throw e
        } finally {
            when {
                apiVersionIsAtLeast(1, 1, 0) -> this.closeFinally(exception)
                this == null -> {}
                exception == null -> close()
                else ->
                    try {
                                            // 여기서 close
                        close()
                    } catch (closeException: Throwable) {
                        // cause.addSuppressed(closeException) // ignored here
                    }
            }
        }
    }

위로

코틀린에서 함수를 다루는 방법

함수 선언 문법

// 코틀린의 접근 지시어는 기본적으로 public, 생략 가능
    fun max(a: Int, b: Int): Int {
        return if (a > b) a else b
    }
    
    // 함수가 하나의 결과값이면 block 대신 '=' 사용 가능
    fun max(a: Int, b: Int): Int = return if (a > b) a else b
    
    // 추론으로 타입 생략 가능
    // 중괄호 대신 '='를 썼기 때문
    // 만약 {...}를 쓰면 명시적으로 타입을 작성해야함
    fun max(a: Int, b: Int) = if (a > b) a else b

default Parameter

자바의 오버로딩으로 인해 같은 메서드가 중복되고 귀찮은 문제를 해결한다.

fun repeat(
        str: String,
        num: Int = 3,
        useNewLine: Boolean = true
    ) {
        for (i in 1..num) {
            if (useNewLine) {
                println(str)
            } else () {
                print(str)
            }
        }
    }

named Argument

builder를 만들지 않고 builder의 장점을 가져갈 수 있다. 코틀린에서 자바 함수를 가져다 쓸 때는 named Argument를 사용할 수 없다. 이유는 JVM에서 자바가 바이트 코드로 변환될 때 파라미터 이름을 갖고 있지 않아 발생한다.

fun main() {
        // named argument
        repeat("Hello World", useNewLine = false)
    }
    
    fun repeat(
        str: String,
        num: Int = 3,
        useNewLine: Boolean = true
    ) {
        for (i in 1..num) {
            if (useNewLine) {
                println(str)
            } else () {
                print(str)
            }
        }
    }

같은 타입의 여러 파라미터 받기 (가변인자)

fun main() {
        printAll("A", "B")
    
        val array = arrayOf("A", "B")
        printAll(*array)
    }
    
    fun printAll(vararg strings: String) {
        for (str in strings) {
            println(str)
        }
    }

위로

반응형

'Language & Framework > Kotlin' 카테고리의 다른 글

특성  (0) 2022.08.05
FP  (0) 2022.08.03
OOP  (0) 2022.08.02
변수, 타입, 연산자  (0) 2022.07.30