고코딩

[Kotlin] 단순 계산기 만들기 본문

코틀린

[Kotlin] 단순 계산기 만들기

고코딩 2022. 1. 29. 17:35

[Kotlin] 단순 계산기 만들기

언어를 가장 빠르게 익히는 방법은 무엇일까? 문법 공부먼저 하는것도 좋지만 바로 뭐라도 만들어보는게 가장 좋다.

Java만 사용해 오던 나는 최근 Kotlin에 관심을 가지기 시작하였고 코틀린을 공부하기 시작했다. 일단 첫번째는 단순 계산기 만들기!!

나는 안드로이드 개발자가 아니니 콘솔창에서 숫자 2개와 연산자 하나를 입력 받으면 결과가 출력이 되게 하겠다.


개발환경

OS : macOS Big Sur

IDE : IntelliJ

Language : Kotlin

목적

코틀린스럽게 만들기.


코드

생각해야 할것들

  • 입력받은 문자를 숫자(Integer)로 변환해주어야 한다.
  • 연산자에 따른 switch를 해주어야 한다.
  • 잘못된 입력일때 예외 처리를 해주어야 한다.

1. 입력받은 문자를 숫자(Integer)로 변환해주어야 한다.

생각해 보니 코틀린에서 문자열 입력받는 방법도 모른다.... 자바에서는 ScannerStringBuffered 를 통해서 입력 받았는데... 바로 구글링 해보았다.

readLine()이라는 함수로 입력을 받는다고 한다. 그럼 이에 String -> Integer 해주어야 하는데 어떻게 해야할까?? 자바에서는 Integer.parseInt() 로 사용하는데 찾아보니 코틀린도 별 다른게 없다... 코틀린 전용 함수가 있다면 알려주시면 감사합니다.

그럼 결국 코드는

val num1: Int = Integer.parseInt(readLine())
val num2: Int = Integer.parseInt(readLine())

이 된다.

2. 연산자에 따른 switch를 해주어야 한다.

자바에서는 if 또는 switch를 이용해서 구간처리를 해준다. 근데 코틀린에서는 switch대신에 when 이라는 표현식이 있다. 이것을 사용해서 구현해보자. 참고로 표현식이란 단순히 말해서 리턴값이 있다는 거다.

코드는 아래와 같다.

val op: String? = readLine()
val result =
    when (op){
    "+" -> num1 + num2
    "-" -> num1 - num2
    "*" -> num1 * num2
    "/" -> num1 / num2
    else -> throw Exception("op is wrong")
  }

이 된다.

여기서 궁금증!!! 잘 보면 num1과 num2의 타입은 Int 이고 op의 타입은 String? 인데 왜 op만 null이 가능한 ? 가 있는 것일까??

힌트는 Integer.parseInt() 는 자바의 함수이고 readLine() 은 코틀린 정적 함수이다. 맥 사용자라면 command + B 를 눌러 함수의 구현부로 가보자.

//Integer.java의 내용
//...
public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
//...


//코틀린의 readLine() 함수 객체으 내용
/**
 * Reads a line of input from the standard input stream.
 *
 * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached.
 */
fun readLine(): String? = LineReader.readLine(System.`in`, Charset.defaultCharset())

잘 모르겠으면 각 함수의 리턴 타입을 보자. parseInt()는 리턴 타입이 int이고 readLine()은 리턴 타입이 String?으로 구현되어 있다. 그래서 당연히 리턴 타입에 맞춰서 변수의 타입을 선언해주어야 한다. 만약 ?의 의미를 잘 모르면 구글링 해보아요~

3. 잘못된 입력일때 예외 처리를 해주어야 한다.

잘못된 입력에는 무엇이 있을까??

  • 숫자를 입력하지 않고 다른 문자를 입력하였을 때
  • op에 사칙연산 구문이 아닌 다른 문자를 입력하였을 때

두번째 예외는 아까 when()을 구현하면서 else에서 예외 처리를 하게 만들었다. 그럼 첫 번째만 처리하면 된다. 그럼 먼저 어떤 예외가 발생하는지 일단은 아래 코드를 실행해 보자.

fun main(args: Array<String>){

    val num1:Int = Integer.parseInt(readLine())
    val op: String? = readLine()
    val num2: Int = Integer.parseInt(readLine())
    val result =
        when(op){
            "+" -> num1 +num2
            "-" -> num1-num2
            "*" -> num1*num2
            "/" -> num1/num2
            else -> throw Exception("op is wrong")
        }

    println("${num1} ${op} ${num2} = ${result}")

}
스크린샷 2022-01-29 오후 5 00 09

정상적으로 입력이 위의 그림과 같은 결과를 얻는다.

스크린샷 2022-01-29 오후 5 03 05

잘못된 입력시 NumberFormatException 예외를 리턴해주는 것을 알 수 있다. 그럼 우리는 try catch를 이용해서 예외 처리 하는 구문을 추가하면 된다.

fun main(args: Array<String>){

    val num1:Int = try{
        Integer.parseInt(readLine())
    }catch (e: NumberFormatException){
        println("잘못된 문자를 입력하였습니다.계산을 종료합니다.")
        return
    }
    val op: String? = readLine()
    val num2: Int = try{
        Integer.parseInt(readLine())
    }catch (e: NumberFormatException){
        println("잘못된 문자를 입력하였습니다. 계산을 종료합니다.")
        return
    }
    val result =
        when(op){
            "+" -> num1 +num2
            "-" -> num1-num2
            "*" -> num1*num2
            "/" -> num1/num2
            else -> throw Exception("op is wrong")
        }

    println("${num1} ${op} ${num2} = ${result}")

}

위와 같이 코드를 리팩토링 해주면 된다.

스크린샷 2022-01-29 오후 5 31 00

정상적으로 예외 처리가 되는 것을 볼 수 있다.


결론

사실 계속해서 입력 받는 처리나 소숫점을 위한 Double형 사용, 코드 함수화 등 여러가지 리팩토링을 해야하지만 뭐 그냥 내가 단순히 코드 익숙해지기 위해서 공부하겠다는 건데 그냥 여기서 끝내겠다. 나중에 코틀린에 대해 좀더 익숙해지면 더 완벽하게 계산기를 만들어 봐야겠다.