scala에서 Exception처리에 대한 다양한 내용을 살펴본다.
1. try-catch
자바와 비슷하게 처리한다.
object Main extends App {
def throwException: Unit = {
try {
println("A".toLong)
} catch {
case ex: Exception => println(ex)
} finally {
println("finally")
}
}
throwException
}
결과는 다음과 같다.
java.lang.NumberFormatException: For input string: "A"
finally
2. scala.util.Try-match
import scala.util.{Failure, Success, Try}
object Main extends App {
def throwException: Any = {
Try {
println("A".toLong)
} match {
case Success(result) => result
case Failure(exception) => exception
}
}
println(throwException)
}
결과는 다음과 같다.
java.lang.NumberFormatException: For input string: "A"
다른 예제
val loginUser =
Try(requestHeader.headers("loginUser")) match {
case Success(user) => user
case _ => ""
}
3. scala.util.Either
Either는 Exception과 결과 값을 한번에 받을 수 있는 타입이다.
def throwException: Either[Long, Throwable] = {
try {
Left("A".toLong)
} catch {
case ex: Exception => Right(ex)
} finally {
println("finally")
}
}
println(throwException)
println(throwException.merge)
결과는 다음과 같다.
finally
Right(java.lang.NumberFormatException: For input string: "A")
finally
java.lang.NumberFormatException: For input string: "A"
merge메소드는 예외와 리턴값 사이의 값을 하나로 병합한다.
4. Exception.allCatch
1,2,3에 연관되어 Exception.allCatch라는 것이 있다. 이를 이용하면 try/catch를 한 줄에 사용할 수도 있다.
import scala.util.control.Exception._
println(allCatch.opt("A".toLong))
println(allCatch.toTry("A".toLong))
println(allCatch.either("A".toLong))
결과는 다음과 같다.
None
Failure(java.lang.NumberFormatException: For input string: "A")
Left(java.lang.NumberFormatException: For input string: "A")
5. scalaz의 disjunction
Either보다 더 좋은 형태의 예외 처리를 할 수 있다.
scala 고수 개발자들이 scalaz의 disjunction을 추천한다고 하니 알아두면 좋을 것 같다.
\/를 사용하면서 해괴하지만, 간단해서 쓴다는...
val m = scalaz.\/.right[Throwable, Int](5).map(_ * 2)
println(m)
println(m.merge)
val n = scalaz.\/.left[Throwable, String](new Exception("1")).map(_.toLong)
println(n)
println(n.merge)
val ez : String \/ String = "a".right
println(ez)
println(ez.merge)
결과는 다음과 같다. Either와 비슷하게 쓰인다. 훨씬 either보다는 편하게 쓸 수 있다.
\/-(10)
10
-\/(java.lang.Exception: 1)
java.lang.Exception: 1
\/-(a)
a
자세한 내용은 scalaz 7.2(https://github.com/scalaz/scalaz/tree/series/7.2.x)를 참고한다.
5. Validation
scalaz의 Validation도 사용할 수 있다.
import scalaz._
def positive(i: Int): Validation[Exception, Int] = {
if (i > 0) Success(i) // <1>
else Failure(new NumberFormatException("should number > 0"))
}
println(positive(1))
println(positive(-1))
'scala' 카테고리의 다른 글
[scala] 부모 클래스를 상속받고 트레이트를 믹스인한 클래스의 생성 순서 (0) | 2016.12.13 |
---|---|
[scala] for 내장 (0) | 2016.12.08 |
[scala] 부분 적용 함수 / 커링 / 부분 함수 (0) | 2016.12.05 |
[scala] 꼬리 재귀(tail recursion)와 @tailrec (0) | 2016.12.05 |
[scala] Future말고 Promise (0) | 2016.11.27 |