选项和选项之间有什么区别? [英] What are the differences between Either and Option?

查看:48
本文介绍了选项和选项之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据文档:

Either 的一个常见用途是作为 Option 的替代来进行交易可能存在缺失值.

A common use of Either is as an alternative to Option for dealing with possible missing values.

你为什么要使用一个?

推荐答案

Either 的好处在于您可以跟踪缺少某些东西的原因.例如,如果您使用 Options,您可能会处于这样的情况:

The nice thing about Either is that you can keep track of the reason something is missing. For example, if you were working with Options, you might be in a situation like this:

val xOpt = Option(1)
val yOpt = Option(2)
val zOpt = None

val tupled = for {
    x <- xOpt
    y <- yOpt
    z <- zOpt
} yield (x, y, z)

现在,如果 tupledNone,我们真的不知道为什么!如果这是其余行为的重要细节,使用 Either 会有所帮助:

Now, if tupled is None, we don't really know why! If this is an important detail for the rest of the behavior, using Either can help:

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),其中消息是第一个缺失值的对应消息,或者 Right(value) 用于元组值.按照惯例,使用 Left 表示失败,使用 Right 表示成功.

This will return either Left(msg) where the message is the first missing value's corresponding message, or Right(value) for the tupled value. It is conventional to keep use Left for failures and Right for successes.

当然,您也可以更广泛地使用 Either,而不仅仅是在值缺失或异常的情况下.在其他情况下,Either 可以帮助表达简单联合类型的语义.

Of course, you can also use Either more broadly, not only in situations with missing or exceptional values. There are other situations where Either can help express the semantics of a simple union type.

用于异常值的第三个常见习语是 Try monad:

The third common idiom to use for exceptional values is the Try monad:

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] 同构.换句话说,您可以将 Try 视为具有左类型 ThrowableEither,并且您可以将任何 Eithercode> 的左类型为 Throwable 作为 Try.此外,Option[A]Try[A] 同态.因此,您可以将 Option 视为忽略错误的 Try.因此,您也可以将其视为一个 Either.事实上,标准库支持其中一些转换:

Try[A] is isomorphic to Either[Throwable, A]. In other words you can treat a Try as an Either with a left type of Throwable, and you can treat any Either that has a left type of Throwable as a Try. Also Option[A] is homomorphic to Try[A]. So you can treat an Option as a Try that ignores errors. Therefore you can also transitively think it as an Either. In fact, the standard library supports some of these transformations:

//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")   

标准库不包括从 EitherTry、从 TryEither 的转换,或从 OptionTry.但是根据需要丰富 OptionTryEither 非常简单:

The standard library does not include the conversions from Either to Try, from Try to Either, or from Option to Try. But it is pretty simple to enrich Option, Try, and Either as needed:

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)

这篇关于选项和选项之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆