如何(最好)将方法调用返回的选项转换为Try (根据喜好,尽管可以使用一个或多个标量\/,甚至是验证),包括在适当的情况下指定一个失败值?
例如,我有以下代码,这让人感觉笨拙,但至少完成了(大部分)工作:
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是否提供了一个合适的,或者有人可以举例说明它会是什么样子?
发布于 2013-07-08 20:10:00
如果你从get go和for-comp的Try开始,那么你可以在结束时消除匹配。您可以通过fold将Option强制到Try来完成此操作。下面是它可能的样子:
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
}使用这种方法,您可以为两个不同的检查获得不同的异常。它不是完美的,但也许它会为你工作。
发布于 2017-07-11 00:47:38
您可以使用隐式转换
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
发布于 2018-03-26 17:33:42
短小精悍
Try(option.get)不需要花哨的映射。如果该选项为空,则会出现如下错误:
java.util.NoSuchElementException: None.gethttps://stackoverflow.com/questions/17521709
复制相似问题