Scala 예외 처리의 기본적인 구조는 Python 이나 Java 와 비슷하지만 사용하는 키워드가 약간 다르고 케이스 클래스와 패턴매칭을 사용한다.
var text = ""
try {
text = ... // 파일을 읽어오는 코드 호출
} catch {
case e: FileNotFoundException => println("File not found")
case e: IOException => println("IO exception occurred")
case _: Throwable => println("default")
} finally {
// 에러 캐치를 하고 나서 실행시키고 싶은 코드
// 예) 데이터베이스 연결 종료
}
Scala는 functional 프로그래밍으로 예외처리를 할 수 있는 수단을 제공한다.
이 기능을 이용해서 type 안정성 뿐만 아니라 null safe 한 코드를 작성할 수 있다.
nullable value를 표현할 때, Option[Type]
을 쓸 수 있다.
def upperString(value: String): Option[String] = {
if (value.isEmpty) None
else Some(value.upper)
}
Option[Type]
으로 선언하고Some(value)
에 넣어서 할당한다.Either 는 "이거 아니면 저거"를 타입으로 만든 것이다. 경우의 수 처리를 안전하게 처리할수 있는 타입이다.
주로 에러를 던질 때, throw로 던지지 않고 처리할 때 사용한다. (주로 left 를 에러로 둔다)
def upperString(value: String): Either[String, String] = {
if (value.isEmpty) Left("Value cannot be empty")
else Right(value.upper)
}
Either[$type_of_error, $type_of_value]
로 선언한다.Try 는 scala 2.10 부터 도입된 새로운 유틸이다.
Either 와 같은 기능을 하면서도 Monadic 하기 때문에 함수형 연산을 바로 이어서 할 수 있다는 점이 특징이다.
import scala.io.StdIn
import scala.util.{Try, Success, Failure}
def divide: Try[Int] = {
val dividend = Try(StdIn.readLine("Enter an Int that you'd like to divide:\n").toInt)
val divisor = Try(StdIn.readLine("Enter an Int that you'd like to divide by:\n").toInt)
val problem = dividend.flatMap(x => divisor.map(y => x/y))
problem match {
case Success(v) =>
println("Result of " + dividend.get + "/" + divisor.get + " is: " + v)
Success(v)
case Failure(e) =>
println("You must've divided by zero or entered something that's not an Int. Try again!")
println("Info from the exception: " + e.getMessage)
divide
}
}
이렇게 실행하면 divide로 return 된 값을 * 10 할 수 있다.
println(divide)
println(divide.map(r=>{r*10}))