catching
похоже, это какой-то вызов метода, не так ли?Это так, но на самом деле он возвращает экземпляр класса 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)
Затем вы можете справиться с этим с помощью map
или filter
или getOrElse
или любым другим способом, который вы используете для работы с опциями.
Другой полезный метод: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
или сопоставить с параметром иливсе, что вам нравится делать с любым из них.
Обратите внимание, что вы можете определить один элемент catcher и использовать его несколько раз (поэтому вам не нужно создавать объект catcher каждый раз, когда вы, например, анализируете целое число):
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)