documentation के अनुसार:या तो और विकल्प के बीच अंतर क्या हैं?
या तो की एक सामान्य उपयोग संभव लापता मूल्यों के साथ निपटने के लिए विकल्प के लिए एक विकल्प के रूप में है।
आप दूसरे पर एक का उपयोग क्यों करेंगे?
documentation के अनुसार:या तो और विकल्प के बीच अंतर क्या हैं?
या तो की एक सामान्य उपयोग संभव लापता मूल्यों के साथ निपटने के लिए विकल्प के लिए एक विकल्प के रूप में है।
आप दूसरे पर एक का उपयोग क्यों करेंगे?
Either
के बारे में अच्छी बात यह है कि आप कारण का कुछ ट्रैक खो सकते हैं। उदाहरण के लिए, यदि आप Options
साथ काम कर रहे थे, तो आप इस तरह एक स्थिति में हो सकता है:
val xOpt = Option(1)
val yOpt = Option(2)
val zOpt = None
val tupled = for {
x <- xOpt
y <- yOpt
z <- zOpt
} yield (x, y, z)
अब, अगर tupled
None
है, हम वास्तव में पता नहीं क्यों! इस व्यवहार के बाकी के लिए एक महत्वपूर्ण विस्तार, Either
का उपयोग कर मदद कर सकते हैं यह है:
val tupled = for {
x <- xOpt.toRight("x is missing").right
y <- yOpt.toRight("y is missing").right
z <- zOpt.toRight("z is missing").right
} yield (x, y, z)
यह या तो Left(msg)
वापस आ जाएगी जहां संदेश पहले लापता मूल्य के लिए इसी संदेश, या tupled मूल्य के लिए Right(value)
है। विफलताओं के लिए Left
और सफलता के लिए Right
का उपयोग करना पारंपरिक है।
बेशक, आप न केवल Either
का उपयोग कर सकते हैं, न केवल लापता या असाधारण मूल्यों की स्थितियों में। ऐसी अन्य स्थितियां हैं जहां Either
एक साधारण यूनियन प्रकार के अर्थशास्त्र को व्यक्त करने में मदद कर सकते हैं।
val xTry = Try("1".toInt)
val yTry = Try("2".toInt)
val zTry = Try("asdf".toInt)
val tupled = for {
x <- xTry
y <- yTry
z <- zTry
} yield (x, y, z)
Try[A]
Either[Throwable, A]
isomorphic को है:
तीसरे आम मुहावरा असाधारण मूल्यों के लिए उपयोग करने के लिए Try
इकाई है। दूसरे शब्दों में आप Throwable
के बाईं प्रकार के साथ एक Try
एक Either
के रूप में इलाज कर सकते हैं, और आप किसी भी Either
एक Try
रूप Throwable
के बाईं प्रकार है कि इलाज कर सकते हैं। Option[A]
Try[A]
पर होमोमोर्फिक है। तो आप Option
को Try
के रूप में देख सकते हैं जो त्रुटियों को अनदेखा करता है। इसलिए आप इसे Either
के रूप में भी सोच सकते हैं। वास्तव में, मानक पुस्तकालय इन परिवर्तनों में से कुछ का समर्थन करता है:
//Either to Option
Left[Int, String](1).left.toOption //Some(1)
Right[Int, String]("foo").left.toOption //None
//Try to Option
Try("1".toInt).toOption //Some(1)
Try("foo".toInt).toOption //None
//Option to Either
Some(1).toRight("foo") //Right[String, Int](1)
(None: Option[Int]).toRight("foo") //Left[String, Int]("foo")
मानक पुस्तकालय रूपांतरण Either
से Try
को, Try
से Either
को शामिल नहीं करता है, या Option
से Try
करने के लिए। लेकिन यह आवश्यक रूप Option
, Try
, और Either
को बेहतर बनाने के बहुत सरल है:
object OptionTryEitherConversions {
implicit class EitherToTry[L <: Throwable, R](val e: Either[L, R]) extends AnyVal {
def toTry: Try[R] = e.fold(Failure(_), Success(_))
}
implicit class TryToEither[T](val t: Try[T]) extends AnyVal {
def toEither: Either[Throwable, T] = t.map(Right(_)).recover(PartialFunction(Left(_))).get
}
implicit class OptionToTry[T](val o: Option[T]) extends AnyVal {
def toTry(throwable: Throwable): Try[T] = o.map(Right(_)).getOrElse(Left(throwable))
}
}
यह तुम क्या करने की अनुमति होगी:
import OptionTryEitherConversions._
//Try to Either
Try(1).toEither //Either[Throwable, Int] = Right(1)
Try("foo".toInt).toEither //Either[Throwable, Int] = Left(java.lang.NumberFormatException)
//Either to Try
Right[Throwable, Int](1).toTry //Success(1)
Left[Throwable, Int](new Exception).toTry //Failure(java.lang.Exception)
//Option to Try
Some(1).toTry(new Exception) //Success(1)
(None: Option[Int]).toTry(new Exception) //Failure(java.lang.Exception)
Either
Option
के सामान्यीकरण के रूप में देखा जा सकता है। आप Unit
को निर्धारित कर उस उदाहरण के लिए Either
के पहले मूल्य, ठीक हैं, तो आप कुछ है कि अनिवार्य रूप से Option
के रूप में एक ही तरह से व्यवहार करती है मिलेगा:
Option[X] := Either[Unit, X]
इस मामले में, Left[Unit, X]
None
के अनुरूप होता है, और Right[Unit, X]
Some[X]
के अनुरूप होगा।
Option[X]
के लिए, None
प्रकार X
के एक मूल्य प्राप्त करने के लिए विफलता किसी तरह का संकेत होता है, और Some[X]
सफलता का संकेत दिया। Either[Unit, X]
के लिए, प्रकार Left[Unit, X]
का उदाहरण विफलता का प्रतिनिधित्व करेगा, और Right[Unit, X]
सफलता का प्रतिनिधित्व करेगा।
हालांकि, अगर आप क्यों कुछ विफल रहा है, या कुछ अतिरिक्त जानकारी आपको एक त्रुटि से उबरने के लिए मदद करता है कि बारे में विस्तृत जानकारी स्टोर करने के लिए Either
के पहले घटक उपयोग कर सकते हैं। Option
आपको सिर्फ None
देता है, जो बहुत उपयोगी नहीं है। लेकिन Either[F,X]
या तो सफलता मूल्य Right[F, X]
लौटा सकता है, जो X
के लिए अनिवार्य रूप से केवल एक रैपर है, या Left[F, X]
में विफलता का विस्तृत विवरण, F
प्रकार की विफलता का प्रतिनिधित्व करने के साथ।
यह आपको अधिक परिष्कृत वसूली रणनीतियों को परिभाषित करने की अनुमति देता है। उदाहरण के लिए, Play के Form.scala
पर एक नज़र डालें! -फ्रेमवर्क। वे पूरे स्थान पर Either
का उपयोग करते हैं, क्योंकि वे या तो उपयोगकर्ता के फॉर्म सबमिशन का जवाब देना चाहते हैं, या आंशिक रूप से भरे हुए फॉर्म को वापस भेजने के लिए, उपयोगी त्रुटि संदेशों के साथ एनोटेटेड हैं। इसका विकल्प Option[TypeOfFormContent]
के साथ काम करना होगा, जो None
का मूल्यांकन करेगा यदि कुछ फॉर्म फ़ील्ड में अमान्य इनपुट था। बदले में इसका मतलब यह होगा कि उपयोगकर्ता को "खराब अनुरोध" जैसे कुछ मिलता है। कृपया पूरा फॉर्म फिर से भरें। " प्रतिक्रिया के रूप में, जो पूरी तरह से परेशान होगा। इसलिए, का उपयोग Option
के बजाय किया जाता है, क्योंकि यह वास्तव में फ़ॉर्म सबमिशन के साथ वास्तव में गलत होने का ट्रैक रख सकता है।
Either
का नुकसान यह है कि यह एक मोनड नहीं है: प्रभावी ढंग से इसके साथ काम करने के लिए, आपको हमेशा दो अलग-अलग मामलों के लिए दो अलग-अलग कॉलबैक पास करना होगा। इसका परिणाम "कॉलबैक-नरक" हो सकता है। इसलिए, किसी को ध्यान से सोचना चाहिए कि असफलता का सटीक वर्णन मूल्यवान है या नहीं। असफल फॉर्म सबमिशन के मामले में, विफलता का एक विस्तृत विवरण मूल्यवान है, क्योंकि कोई उपयोगकर्ता को फिर से सब कुछ फिर से टाइप करने के लिए मजबूर नहीं करना चाहता है। अन्य मामलों में, Option
अधिक उपयुक्त हो सकता है, क्योंकि कोई प्रोग्रामर को अप्राप्य त्रुटियों के अनावश्यक विस्तृत विवरणों से निपटने के लिए मजबूर नहीं करना चाहता है।
एंड्री ट्यूकिन वापस आ गया है! मुझे हालांकि स्वीकार करना है- मैं थोड़ा निराश हूं कि आपने अपने उत्तर के लिए [एक और भयानक आरेख] (http://stackoverflow.com/a/19739576/1427124) एक साथ नहीं रखा है। – DaoWen
@ दाओवेन: मुझे लगता है कि मुझे निश्चित रूप से अपने "इंटरनेट-एल्टर-अहो" के बारे में कुछ करना चाहिए, क्योंकि वर्तमान में ऐसा लगता है जैसे जलती हुई शाकाहारी पांडा का एक हास्यास्पद gif-painting मेरा सबसे महत्वपूर्ण विचार है। तीन महीने या उससे भी ज्यादा में इसके बारे में कुछ करने के लिए। –