관리 메뉴

나만을 위한 블로그

[Algorithm] 프로그래머스 - 문자열 출력하기 (Kotlin) 본문

알고리즘 문제 풀이/프로그래머스

[Algorithm] 프로그래머스 - 문자열 출력하기 (Kotlin)

참깨빵위에참깨빵_ 2023. 11. 25. 19:16
728x90
반응형
문자열 str이 주어질 때 str을 출력하는 코드를 작성하라

 

 

문자열을 받으면 그것을 그대로 출력하면 해결되는 문제다.

코틀린에서 별다른 추가사항 없이 문자열을 출력하는 함수는 print(), println()이 있다. 둘 중 어느 것을 사용하더라도 테스트는 통과된다. 여기선 println()을 사용한다.

 

fun main(args: Array<String>) {
    val s1 = readLine()!!
}

 

문제 오른쪽 코드 에디터에 위와 같이 작성돼 있는데, !! 기호는 readLine()을 호출한 결과가 널이 아닌 값이 반드시 존재한다는 뜻이다. 해당 값이 널이 아님을 보증하는 기호기 때문에, 널이 들어온다면 프로그램 실행 중 이 부분에서 에러가 발생하며 프로그램이 강제종료된다.

먼저 널 같은 거 생각하지 않고 작성하겠다면 아래와 같이 할 수 있다.

 

fun main(args: Array<String>) {
    val s1 = readLine()!!
    println(s1)
}

 

더 간단하게 한다면, println() 안에 출력할 문자열을 넣는 대신 readLine()!! 자체를 넣을 수 있다.

s1을 넣든, readLine()!!을 넣든 println()이 출력할 것은 똑같기 때문이다.

 

fun main(args: Array<String>) {
    println(readLine()!!)
}

 

그리고 코틀린에는 식이 본문인 함수라는, 등호와 식으로만 구성된 함수 형태를 제공하기 때문에 위 코드는 아래와 같이 간결하게 표현될 수 있다.

 

fun main(args: Array<String>) = println(readLine()!!)

 

추가로 !!을 사용하지 않으려면 어떻게 해야 할지 궁금할 수 있다. 코틀린에는 널이 될 수 있는 변수에 접근할 수 있는 여러 키워드를 제공하는데 그 중 하나가 안전한 호출 연산자(?.)다.

 

fun main(args: Array<String>) {
    readLine()?.let {
        println(it)
    }
}

 

let {}은 범위 지정 함수 5가지 중의 하나로, let 블록 왼쪽의 객체를 중괄호 블록(람다) 안에 넘기고, 블록 안에선 그 값을 사용해 여러 처리를 한 다음 마지막 줄을 리턴하는 함수다. 본 적 없는 키워드라면 코틀린의 범위 지정 함수를 찾아서 공부해보면 된다.

람다 안에서 let을 통해 전달받은 객체는 기본적으로 it이란 이름으로 쓸 수 있어서 println()의 매개변수로 it을 넘기는 걸 볼 수 있다. it이 아니라 line, sentence 등 다양한 이름으로 바꿀 수 있다.

 

위 코드를 식이 본문인 함수로 바꿀 수 있을까? 당연히 바꿀 수 있다.

 

fun main(args: Array<String>) = readLine()?.let {
    println(it)
}

 

하지만 이 코드를 제출하면 실패한다. 왜 실패할까?

safe call(?.) 연산자는 앞에 널이 될 수 있는 변수가 들어온다. 하지만 main 함수의 리턴타입은 String? 이나 Int? 처럼 nullable한 타입이 아니다. 그래서 널이 아닌 경우에 대한 처리도 같이 해줘야 한다.

 

fun main(args: Array<String>) = readLine()?.let {
    println(it)
} ?: println()

 

이렇게 하면 readLine()의 값이 널인 경우 공백을 출력하고, 널이 아니면 그 값을 출력하는 main 함수가 완성된다.

하지만 굳이 공백을 출력해야 할 이유가 없다. 그래서 문제의 코드를 하나만 제출해야 한다면 나는 아래 코드를 제출할 것이다. 선택은 본인 몫

 

fun main(args: Array<String>) {
    readLine()?.let {
        println(it)
    }
}
반응형
Comments