首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何(最好)将选项转换为Try?

如何(最好)将选项转换为Try?
EN

Stack Overflow用户
提问于 2013-07-08 16:05:41
回答 7查看 15.2K关注 0票数 21

如何(最好)将方法调用返回的选项转换为Try (根据喜好,尽管可以使用一个或多个标量\/,甚至是验证),包括在适当的情况下指定一个失败值?

例如,我有以下代码,这让人感觉笨拙,但至少完成了(大部分)工作:

代码语言:javascript
复制
import scala.util._

case class ARef(value: String)
case class BRef(value: String)
case class A(ref: ARef, bRef: BRef)
class MismatchException(msg: String) extends RuntimeException(msg)

trait MyTry {

  // Given:
  val validBRefs: List[BRef]

  // Want to go from an Option[A] (obtained, eg., via a function call passing a provided ARef)
  // to a Try[BRef], where the b-ref needs to be checked against the above list of BRefs or fail:

  def getValidBRefForReferencedA(aRef: ARef): Try[BRef] = {

    val abRef = for {
      a <- get[A](aRef) // Some function that returns an Option[A]
      abRef = a.bRef
      _ <- validBRefs.find(_ == abRef)
    } yield (abRef)

    abRef match {
      case Some(bRef) => Success(bRef)
      case None => Failure(new MismatchException("No B found matching A's B-ref"))
    }
  }
}

感觉应该有一种方法可以将最终的比赛变形为地图或flatMap或类似的构造,并将其合并到前言中以便于理解。

此外,如果从ARef返回OptionA的调用失败(返回None)与BRef检查失败(我只关心知道失败的一个原因,所以scalaz验证感觉不太合适)相比,我更希望能够指定不同的失败消息。

这是使用monad transformer的合适地方吗?如果是这样的话,scalaz是否提供了一个合适的,或者有人可以举例说明它会是什么样子?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-07-08 20:10:00

如果你从get go和for-comp的Try开始,那么你可以在结束时消除匹配。您可以通过foldOption强制到Try来完成此操作。下面是它可能的样子:

代码语言:javascript
复制
def getValidBRefForReferencedA(aRef: ARef): Try[BRef] = {
  for {
    a <- get[A](aRef).fold[Try[A]](Failure[A](new OtherException("Invalid aRef supplied")))(Success(_))
    abRef = a.bRef
    _ <- validBRefs.find(_ == abRef).fold[Try[BRef]](Failure(new MismatchException("No B found matching A's B-ref")))(Success(_))
  } yield abRef
}

使用这种方法,您可以为两个不同的检查获得不同的异常。它不是完美的,但也许它会为你工作。

票数 8
EN

Stack Overflow用户

发布于 2017-07-11 00:47:38

您可以使用隐式转换

代码语言:javascript
复制
  implicit class OptionOps[A](opt: Option[A]) {

    def toTry(msg: String): Try[A] = {
      opt
        .map(Success(_))
        .getOrElse(Failure(new NoSuchElementException(msg)))
    }
  }

Scala标准库使用这种方法。请参阅http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html#companion-objects-of-a-type

票数 17
EN

Stack Overflow用户

发布于 2018-03-26 17:33:42

短小精悍

代码语言:javascript
复制
Try(option.get)

不需要花哨的映射。如果该选项为空,则会出现如下错误:

代码语言:javascript
复制
java.util.NoSuchElementException: None.get
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17521709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档