Пакет scala.util.control
пакет control
Члены типа
класс Breaks extends AnyRef
абстрактный класс ControlThrowable extends Throwable
Родительский класс для объектов-исключений, предназначенных для управления потоком.
Экземпляры ControlThrowable обычно не должны перехватываться.
Для удобства, NonFatal не соответствует ControlThrowable.
import scala.util.control.{Breaks, NonFatal}, Breaks.{break, breakable}
breakable {
for (v <- values) {
try {
if (p(v)) break
else ???
} catch {
case NonFatal(t) => log(t) // can't catch a break
}
}
}
Подавление отключено, так как управление потоком не должно подавлять исключительное состояние. Отладочные трассы также отключены, что позволяет безопасно повторно использовать экземпляры ControlThrowable.
Экземпляры ControlThrowable обычно не должны иметь причину. Подклассы старого стиля могут устанавливать причину с помощью initCause.
трайт NoStackTrace extends Throwable
Трейт для исключений, которые по причинам эффективности не заполняют стек вызовов. Подавление стека вызовов можно отключить глобально, используя системную переменную в scala.sys.SystemProperties.
- Since
2.8
- Примечание
Начиная с JDK 1.7, аналогичный эффект можно получить с помощью
class Ex extends Throwable(..., writableStackTrace = false)
Значения членов
объект Breaks extends Breaks
Объект, который может использоваться для абстракции управления разрывом. Пример использования:
import Breaks.{break, breakable}
breakable {
for (...) {
if (...) break
}
}
объект Exception
Классы, представляющие компоненты обработки исключений.
Каждый класс независимо компонуем.
Этот класс отличается от scala.util.Try тем, что фокусируется на композиции обработчиков исключений, а не композиции поведения. Все поведение должно быть составлено предварительно и передано объекту Catch с помощью одного из opt, either или withTry методов. Взятые вместе, классы предоставляют DSL для композиции поведения catch и finally.
Примеры
Создайте Catch, который обрабатывает указанные исключения.
import scala.util.control.Exception._
import java.net._
val s = "http://www.scala-lang.org/"
// Some(http://www.scala-lang.org/)
val x1: Option[URL] = catching(classOf[MalformedURLException]) opt new URL(s)
// Right(http://www.scala-lang.org/)
val x2: Either[Throwable,URL] =
catching(classOf[MalformedURLException], classOf[NullPointerException]) either new URL(s)
// Success(http://www.scala-lang.org/)
val x3: Try[URL] = catching(classOf[MalformedURLException], classOf[NullPointerException]) withTry new URL(s)
val defaultUrl = new URL("http://example.com")
// URL(http://example.com) because htt/xx throws MalformedURLException
val x4: URL = failAsValue(classOf[MalformedURLException])(defaultUrl)(new URL("htt/xx"))
Создайте Catch, который регистрирует исключения, используя handling и by.
def log(t: Throwable): Unit = t.printStackTrace
val withThrowableLogging: Catch[Unit] = handling(classOf[MalformedURLException]) by (log)
def printUrl(url: String) : Unit = {
val con = new URL(url) openConnection()
val source = scala.io.Source.fromInputStream(con.getInputStream())
source.getLines.foreach(println)
}
val badUrl = "htt/xx"
// Prints stacktrace,
// java.net.MalformedURLException: no protocol: htt/xx
// at java.net.URL.<init>(URL.java:586)
withThrowableLogging { printUrl(badUrl) }
val goodUrl = "http://www.scala-lang.org/"
// Prints page content,
// <!DOCTYPE html>
// <html>
withThrowableLogging { printUrl(goodUrl) }
Используйте unwrapping, чтобы создать Catch, который распаковывает исключения перед повторной передачей.
class AppException(cause: Throwable) extends RuntimeException(cause) val unwrappingCatch: Catch[Nothing] = unwrapping(classOf[AppException]) def calcResult: Int = throw new AppException(new NullPointerException) // Throws NPE not AppException, // java.lang.NullPointerException // at .calcResult(<console>:17) val result = unwrappingCatch(calcResult)
Используйте failAsValue, чтобы предоставить значение по умолчанию, когда перехватывается указанное исключение.
val inputDefaulting: Catch[Int] = failAsValue(classOf[NumberFormatException])(0) val candidatePick = "seven" // scala.io.StdIn.readLine() // Int = 0 val pick = inputDefaulting(candidatePick.toInt)
Комбинируйте несколько Catch с or, чтобы создать Catch, предоставляющий значения по умолчанию, отличающиеся по исключениям.
val formatDefaulting: Catch[Int] = failAsValue(classOf[NumberFormatException])(0)
val nullDefaulting: Catch[Int] = failAsValue(classOf[NullPointerException])(-1)
val otherDefaulting: Catch[Int] = nonFatalCatch withApply(_ => -100)
val combinedDefaulting: Catch[Int] = formatDefaulting or nullDefaulting or otherDefaulting
def p(s: String): Int = s.length * s.toInt
// Int = 0
combinedDefaulting(p("tenty-nine"))
// Int = -1
combinedDefaulting(p(null: String))
// Int = -100
combinedDefaulting(throw new IllegalStateException)
// Int = 22
combinedDefaulting(p("11"))
объект NoStackTrace extends java.io.Serializable
объект NonFatal
Экстрактор некритичных Throwables. Не будет соответствовать критическим ошибкам, таким как VirtualMachineError (например, OutOfMemoryError и StackOverflowError, подклассы VirtualMachineError), ThreadDeath, LinkageError, InterruptedException, ControlThrowable.
Обратите внимание, что scala.util.control.ControlThrowable, внутренний тип Throwable, не соответствует NonFatal (и, следовательно, будет переброшен).
Например, все безобидные Throwables могут быть перехвачены:
try {
// dangerous stuff
} catch {
case NonFatal(e) => log.error(e, "Something not that bad.")
// or
case e if NonFatal(e) => log.error(e, "Something not that bad.")
}
объект TailCalls
Методы, экспортированные этим объектом, реализуют вызовы хвоста с помощью перебрасывания. Методы с вызовом хвоста должны возвращать результат, используя done или вызывать следующий метод с помощью tailcall. Оба возвращают объект TailRec. Результат вычисления хвостового вызова функции можно получить из значения Tailrec с помощью метода result. Реализовано как описано в "Stackless Scala with Free Monads" http://blog.higher-order.com/assets/trampolines.pdf
Вот пример использования:
import scala.util.control.TailCalls._
def isEven(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(true) else tailcall(isOdd(xs.tail))
def isOdd(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail))
isEven((1 to 100000).toList).result
def fib(n: Int): TailRec[Int] =
if (n < 2) done(n) else for {
x <- tailcall(fib(n - 1))
y <- tailcall(fib(n - 2))
} yield (x + y)
fib(40).result
© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.13.0/scala/util/control/index.html
Класс, который можно использовать для абстракции управления разрывом. Пример использования:
val mybreaks = new Breaks import mybreaks.{break, breakable} breakable { for (...) { if (...) break() } }Вызовы break из одного экземпляра
Breaksникогда не будут нацелены на объекты, подлежащие разрыву, в другом экземпляре.