Scala 捕捉混乱

发布于 2024-11-02 07:01:02 字数 231 浏览 0 评论 0原文

我最近看到过这样的代码:

val maybeInt = catching(classOf[NFE]) opt arg.toInt

What is this opt?一个选择?为什么不使用 getOrElse 来提取值?在上面的代码中,如果抛出 NumberFormatException,maybeInt 会是 None 吗?

I've recently seen code like this:

val maybeInt = catching(classOf[NFE]) opt arg.toInt

What is this opt? An Option? Why isn't it using getOrElse to extract the value? In the above code, will maybeInt be None if a NumberFormatException gets thrown?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

各自安好 2024-11-09 07:01:02

捕捉 看起来像是某种方法调用,不是吗?确实如此,但它实际上返回了类 Catch 的实例;它不直接接受参数。此类有两个对于处理异常特别有用的方法(还有几个用于捕获多个异常)。第一个是

def opt [U >: T] (body: ⇒ U) : Option[U]

这里使用的——你给它一些可能抛出异常的东西,如果一切顺利,它会返回 Some(result) ,如果一切顺利,它会返回 None捕获了目标异常:

scala> type NFE = NumberFormatException
defined type alias NFE

scala> import scala.util.control.Exception._
import scala.util.control.Exception._

scala> catching(classOf[NFE]).opt( "fish".toInt )
res0: Option[Int] = None

scala> catching(classOf[NFE]).opt( "42".toInt )  
res1: Option[Int] = Some(42)

然后您可以使用 mapfiltergetOrElse 或任何其他用于处理选项的内容来处理此异常。

另一个有用的方法是 either,如果抛出异常则返回 Left(exception) 实例,如果抛出异常则返回 Right(result)事实并非如此:

scala> catching(classOf[NFE]).either( "fish".toInt )
res2: Either[Throwable,Int] = Left(java.lang.NumberFormatException: For input string: "fish")

scala> catching(classOf[NFE]).either( "42".toInt )
res3: Either[Throwable,Int] = Right(42)

然后您可以使用fold或映射到一个选项或您喜欢用其中任何一个做的任何其他事情。

请注意,您可以定义一个捕获器并多次使用它(因此您不需要每次解析整数时都创建捕获器对象):

scala> val catcher = catching(classOf[NFE])
catcher: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)

scala> catcher.opt("42".toInt)
res4: Option[Int] = Some(42)

scala> catcher.opt("fish".toInt)
res5: Option[Int] = None

编辑:正如丹尼尔在评论中指出的那样,这仍然会创建临时的Catch[Option];给定方法签名,没有一种简单的方法可以让它捕获异常并生成选项而不创建任何额外的对象。这让我想起了为什么我要编写自己的方法来做到这一点:

def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None}
optNFE( "fish".toInt )  // gives None
optNFE( "42".toInt ) // gives Some(42)

catching looks like it's some sort of method call, doesn't it? It is, but it actually returns an instance of a class Catch; it doesn't directly take an argument. This class has two methods that are particularly useful for dealing with exceptions (and several more for catching multiple exceptions). The first is

def opt [U >: T] (body: ⇒ U) : Option[U]

which is being used here--you give it something that may throw an exception, and it will return Some(result) if everything went okay, and None if the targeted exception was caught:

scala> type NFE = NumberFormatException
defined type alias NFE

scala> import scala.util.control.Exception._
import scala.util.control.Exception._

scala> catching(classOf[NFE]).opt( "fish".toInt )
res0: Option[Int] = None

scala> catching(classOf[NFE]).opt( "42".toInt )  
res1: Option[Int] = Some(42)

You can then deal with this with map or filter or getOrElse or whatever else you use to deal with options.

The other useful method is either, which returns an instance of Left(exception) if an exception was thrown, and a Right(result) if it was not:

scala> catching(classOf[NFE]).either( "fish".toInt )
res2: Either[Throwable,Int] = Left(java.lang.NumberFormatException: For input string: "fish")

scala> catching(classOf[NFE]).either( "42".toInt )
res3: Either[Throwable,Int] = Right(42)

You can then use fold or map to an option or whatever else you like doing with eithers.

Note that you can define a single catcher and use it multiple times (so you don't need to create the catcher object every time you, for example, parse an integer):

scala> val catcher = catching(classOf[NFE])
catcher: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)

scala> catcher.opt("42".toInt)
res4: Option[Int] = Some(42)

scala> catcher.opt("fish".toInt)
res5: Option[Int] = None

Edit: as Daniel points out in the comments, this still creates a temporary Catch[Option]; given the method signatures, there isn't an easy way to just have it trap exceptions and generate options without creating any extra objects. This reminds me why I write my own methods to do exactly that:

def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None}
optNFE( "fish".toInt )  // gives None
optNFE( "42".toInt ) // gives Some(42)
慢慢从新开始 2024-11-09 07:01:02

当只有一个问题时,我使用一种更简单的模式:

 try{
      return args.split(" ").exists(line.startsWith _)
 }catch {
    case _ =>{//generic exception
      logger.error("Error with line ${line} for ${ex.message}")
      throw _
    }    
 }

我绝对还不是 Scala 专业人士,我想你可以找到更短的东西

I use a more simple pattern when there is only one catch :

 try{
      return args.split(" ").exists(line.startsWith _)
 }catch {
    case _ =>{//generic exception
      logger.error("Error with line ${line} for ${ex.message}")
      throw _
    }    
 }

I'm definitely not yet a Scala pro, and I guess you could find shorter stuff

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文