2016-11-28 31 views
5

जवाब के लिए ऑनलाइन सर्च कर रहे हैं दो प्रमुख पदों (Codacy's और Daniel 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 
    } 
} 

लेकिन मैं कर सकते हैं बस के रूप में आसानी से पाइप लाइन पारंपरिक 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 
} 

(नोट: divide और divideConventional थोड़ा व्यवहार में मतभेद उसमें बाद में परेशानी के पहले संकेत पर त्रुटियां होती हैं, लेकिन यह इसके बारे में है। dividend पर इनपुट के रूप में "10a" दर्ज करने का प्रयास करें मेरा मतलब है।)

मैं scala.util.Try के पाइपलाइनिंग लाभ को देखने की कोशिश कर रहा हूं, लेकिन मेरे लिए ऐसा लगता है कि दो विधियां बराबर हैं। मैं क्या खो रहा हूँ?

+1

ध्यान दें कि 'कोशिश करें (...)' केवल गैर-घातक अपवादों को पकड़ता है, इसलिए यह {try {...} पकड़ {केस NonFatal (e) => ...} –

+0

के बराबर है ध्यान दें कि 'कोशिश करें' प्रकार प्रणाली का हिस्सा है। कोई भी कोड जो 'Try'' प्रकार के मान को संभालता है, जानता है कि यह एक या दूसरे हो सकता है। एक नियमित जो फेंक सकता है उसे 'कोशिश करें' में लपेट सकता है और किसी और की समस्या के रूप में इसे पास कर सकता है। 'कोशिश करें' के बिना संवाद करने का कोई आसान तरीका नहीं है, "अरे! किसी और को इसे संभालने की जरूरत है।" – jwvh

+1

डैनियल वेस्टहाइड ने अपनी पोस्ट में कहा है कि "अगर आपको किसी अन्य थ्रेड पर निष्पादित एक अभिनेता द्वारा फेंक दिया गया अपवाद से निपटने की ज़रूरत है, तो आप स्पष्ट रूप से उस अपवाद को पकड़कर ऐसा नहीं कर सकते हैं।" मुझे लगता है कि समेकन मुद्दा भी महत्वपूर्ण है। – NaHeon

उत्तर

4

मुझे लगता है कि आपको Try[T] की रचना क्षमताओं को देखने में कठिनाई हो रही है क्योंकि आप दोनों मामलों में स्थानीय रूप से अपवादों को संभालने में सक्षम हैं। क्या होगा यदि आप अतिरिक्त ऑपरेशन के साथ divideConventional लिखना चाहते हैं?

हम होने चाहते कुछ की तरह:

def weNeedAnInt(i: Int) = i + 42 

फिर हम की तरह कुछ होगा:

weNeedAnInt(divideConventional()) 

लेकिन मान लीजिए कि आप पुनर्प्रयास की संख्या का पता अधिकतम करना चाहते हैं आप के लिए उपयोगकर्ता की अनुमति देने के जाने इनपुट (जो आम तौर पर वास्तविक जीवन परिदृश्य में आपके पास है, जहां आप हमेशा के लिए एक विधि फिर से दर्ज नहीं कर सकते हैं? हमें weNeedAnInt के साथ try-catch:

के साथ स्वयं को आमंत्रित करना होगा
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] को अगले में लिख सकते हैं, और केवल पाइपलाइन पूर्ण होने पर समस्याओं के बारे में चिंता करें।

संबंधित मुद्दे