2016-11-28 10 views
5

두 눈에 잘 띄는 게시물 (Codacy'sDaniel Westheide's)를 제공하고, 모두 Scala's official documentation for Try과 같은 답변을 제공 :scala.util.Try는 어떤 장점을 가지고 있습니까? 대답 온라인 검색

위의 예에서와 같이보십시오의 중요한 특성은 파이프 라인의 능력, 또는 체인을 , 작업, 길을 따라 예외를 잡기.

위에서 언급 한 예는 다음

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 
    } 
} 

하지만 I 수 종래 try 블록 사용 마찬가지로 쉽게 파이프 라인 동작 :

def divideConventional: Int = try { 
    val dividend = StdIn.readLine("Enter an Int that you'd like to divide:\n").toInt 
    val divisor = StdIn.readLine("Enter an Int that you'd like to divide by:\n").toInt 
    val problem = dividend/divisor 
    println("Result of " + dividend + "/"+ divisor +" is: " + problem) 
    problem 
} catch { 
    case (e: Throwable) => 
    println("You must've divided by zero or entered something that's not an Int. Try again!") 
    println("Info from the exception: " + e.getMessage) 
    divideConventional 
} 

는 (주

: dividedivideConventional 행동이 약간 달라을 후자가 문제의 첫 징후에서 벗어난다는 점에서 그렇습니다.하지만 그것에 관한 것입니다. dividend에 입력으로 "10a"를 입력하여 wh를 확인하십시오 내 뜻은.)

나는이 파이프 라인의 이점을 보려고하는데, 두 가지 방법이 같다. 내가 뭘 놓치고 있니?

+1

'try (...)'는 치명적이지 않은 예외 만 잡아 냄에주의하십시오. 'try {...} catch {case NonFatal (e) => ...} –

+0

'Try ' 유형 시스템의 일부입니다. 'Try' 타입의 값을 처리하는 모든 코드는 그것이 하나가 될 수도 있다는 것을 안다. 던질 수있는 루틴은'Try'로 랩핑하여 다른 사람의 문제로 넘길 수 있습니다. '시도'가 없으면 쉽게 의사 소통 할 수있는 방법이 없습니다. "이봐, 다른 사람이 처리해야 해." – jwvh

+1

Daniel Westheide는 "다른 스레드에서 실행되는 Actor가 던진 예외를 처리해야하는 경우 해당 예외를 잡아 당겨도 분명히이를 수행 할 수 없습니다."라고 그의 게시물에서 말합니다. 동시성 문제도 중요하다고 생각합니다. – NaHeon

답변

4

두 경우 모두에서 예외를 처리하기 때문에 구성 가능성이 Try[T] 인 것을 보는 데 어려움이 있다고 생각합니다. 추가 작업으로 divideConventional을 작성하고 싶다면 어떻게해야합니까?

우리는 가진 거라고 몇 가지 같은 :

def weNeedAnInt(i: Int) = i + 42 

그런 다음 우리는 같은 거라고 :

weNeedAnInt(divideConventional()) 

를하지만의 당신이 사용자를 허용 재시도 횟수에서 최대 원하는 가정 해 봅시다 입력 (대개 실생활 시나리오에서 영원히 메소드를 다시 입력 할 수없는 경우) : :

와 함께 호출을 추가로 랩핑해야합니다
try { 
    weNeedAnInt(divideConventional()) 
} catch { 
    case NonFatal(e) => // Handle? 
} 

그러나 우리는 divide을 사용하고,의는 로컬 예외를 처리하지 않은 가정 해 봅시다 바깥쪽으로 내부 예외를 propogated 경우 :

def yetMoreIntsNeeded(i: Int) = i + 64 

val result = divide.map(weNeedAnInt).map(yetMoreIntsNeeded) match { 
    case Failure(e) => -1 
    case Success(myInt) => myInt 
} 

println(s"Final output was: $result") 

이 간단 아닌가? 아마, 나는 이것이 대답에 대한 주관성을 가지고 있다고 생각한다. 나는 그것을 더 깨끗하게 발견한다. 우리가 그러한 작업의 긴 파이프 라인을 가지고 있다고 가정하면, 각각의 Try[T]을 다음으로 구성 할 수 있으며 일단 파이프 라인이 완료되면 문제에 대해서만 걱정할 수 있습니다.