当前位置:  开发笔记 > 编程语言 > 正文

在Scala中将选项转换为Either

如何解决《在Scala中将选项转换为Either》经验,为你挑选了2个好方法。

假设我需要在Scala中转换Option[Int]Either[String, Int].我想这样做:

def foo(ox: Option[Int]): Either[String, Int] =
  ox.fold(Left("No number")) {x => Right(x)}

不幸的是上面的代码没有编译,我需要Either[String, Int]显式添加类型:

ox.fold(Left("No number"): Either[String, Int]) { x => Right(x) }

是否可以在不添加类型的情况下转换OptionEither这种方式?
您如何建议转换OptionEither



1> Jesper..:

不,如果你这样做,你不能忽略这种类型.

Left("No number")推断的类型是Either[String, Nothing].从刚才Left("No number")的编译器无法知道你想要的第二种类型的EitherInt,和类型推断并不到目前为止,编译器将着眼于整个方法,并决定它应该去Either[String, Int].

您可以通过多种不同方式完成此操作.例如,使用模式匹配:

def foo(ox: Option[Int]): Either[String, Int] = ox match {
  case Some(x) => Right(x)
  case None    => Left("No number")
}

或者用if表达式:

def foo(ox: Option[Int]): Either[String, Int] =
  if (ox.isDefined) Right(ox.get) else Left("No number")

或者Either.cond:

def foo(ox: Option[Int]): Either[String, Int] =
  Either.cond(ox.isDefined, ox.get, "No number")


并且还有`ox.toRight("No Number")`但是因为这个方法没有显式的返回类型,所以它被推断为`Serializable with Product with the [String,Int]`

2> Peter Perháč..:

我不确定您当时使用的是哪个版本的Scala.目前,使用Scala 2.12.6,您的代码没有编译问题,如下所示:

def foo(ox: Option[Int]): Either[String, Int] =
  ox.toRight("No number")

我想提出的另一点是折叠(虽然它是我首选折叠任何有折叠方法的方法),但通常需要有关类型参数的帮助.编译器可以通过两种方式检查表达式,它可以推断出类型参数,也可以简单地找到明确定义的参数.

在您的示例中,如果您尝试折叠选项,请执行以下操作:

def foo(ox: Option[Int]): Either[String, Int] =
  ox.fold(Left("No number") : Either[String, Int])(x => Right(x))

您明确提供有关第一个参数的类型信息,然后可以使用它来推断类型参数fold.你正在帮助类型推断机制.

另一方面,您可以简单地显式提供类型参数,fold如下所示:

def foo(ox: Option[Int]): Either[String, Int] =
  ox.fold[Either[String, Int]](Left("No number"))(x => Right(x))

现在你的实际(值级)参数没有多余的类型信息,并且当编译器查看它时没有类型推断,它可以立即告诉什么fold类型参数,因为它已经明确提供.使用方括号显式指定类型参数.

还有一点,关于x => Right(x)这里你实际上是在创建一个新的函数文字,除了将x传递apply给Right case类的伴随对象的方法之外什么都不做.您已经拥有适当形状的功能.它需要x并返回一个Right(x).这是apply方法.你可以直接引用它(传递它).

def foo(ox: Option[Int]): Either[String, Int] =
  ox.fold[Either[String, Int]](Left("No number"))(Right.apply)

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有