본문 바로가기

코틀린

1장 - 테스트에 도전해 보세요(정답 해설)

문제 6번에 대해서만 정답 해설을 제공합니다.

문제 6 
(1) 아래 코드를 실행하면 어떤 종류의 예외(Exception)가 발생할까요? NumberFormatException. 예외는 실행 시간(run time)에 발생하는 에러입니다.

fun main() {
    val s = "12x"  // 소문자 x
    println(s.toInt())
}


(2) 왜 예외가 발생했나요? 숫자 문자('0', '1',..., '9')만 Int 타입으로 변환할 수 있기 때문
(3) 예외가 발생하지 않도록 아래 코드를 수정해 보세요. 

첫 번째 답안: 대부분 아래처럼 코딩하지 않았을까요? if 문에서 숫자 문자인지를 조사합니다.

fun main() {
    val s = "12x"  // 소문자 x
    
    if (isAllLetters(s)) {
        println(s.toInt())
    } else {
        println("[$s] cannot convert into Integers.")
    }
}

fun isAllLetters(s: String): Boolean {
    for (c in s) {
        if (!c.isDigit()) return false
    }
    return true
}
 

첫 번째 답안의 여러 가지 변형(variations): if 문의 조건식에 범위 타입을 사용하는 방법입니다.

fun isAllLetters(s: String): Boolean {
    for (c in s) {
        if (c !in '0'..'9') return false
    }
    return true
}

 

첫 번째 답안의 여러 가지 변형(variations):  for 루프에서 인덱스 범위를 사용할 수 있습니다. s.lastIndex는 String 타입 객체 s의 마지막 인덱스(=2)입니다.

fun isAllLetters(s: String): Boolean {
    for (i in 0..s.lastIndex) {
        if (s[i] !in '0'..'9') return false
    }
    return true
}

 

첫 번째 답안의 여러 가지 변형(variations):  for 루프 대신 표준 라이브러리 함수 all()을 사용하면 1줄 코딩이 가능합니다. all() 함수는 수신자 객체인 s의 모든 원소가 숫자 문자이면 true, 하나라도 숫자 문자가 아니면 false를 반환합니다.

fun isAllLetters(s: String): Boolean {
    return s.all { it.isDigit() }
}

 

두 번째 답안 : 첫 번째 답안과 비슷하지만 try-catch 블록과 throw 문을 사용해 코드를 강인(robust)하게 만드는 것입니다. throw 문에서 정의한 문자열이 catch 블록에서 에러 메시지로 전달됩니다.

fun main() {
    val s = "12x"  // 소문자 x
    try {
        if (isAllLetters(s)) {
            println(s.toInt())
        }
    } catch (e: NumberFormatException) {
        println("Exception: ${e.message}")
    }
}

fun isAllLetters(s: String): Boolean {
    val result: Boolean = s.all { it.isDigit() }
    if (!result)
        throw NumberFormatException("$s have non-digit char(s)")
    return true
}

 

세 번째 답안:  첫 번째 답안과 두 번째 답안을 결합한 형태입니다. 심지어 숫자 문자인지 함수를 만들어 체크할 필요도 없죠! try-catch 블록으로 둘러싸면 끝입니다. 여기서 제시한 답 이외에 여러분은 어떤 재미있는 답안을 작성했나요?

fun main() {
    val s = "12x"  // 소문자 x
    try {
        println(s.toInt())
    } catch (e: NumberFormatException) {
        println("$s have non-digit char(s): ${e.message}")
    }
}

 

코딩은 예술(art)입니다. 어떤 목적으로 코딩하느냐에 따라 코드는 얼마든 달라질 수 있습니다. 예술 작품에 점수를 매길 수 있나요? 아니죠. 미적 감각에 차이가 있을 뿐이죠. 코딩도 마찬가지입니다.