Spec-Zone.ru › Scala 2.13 Library

Пакет scala.util.control

пакет control

Члены типа

класс Breaks extends AnyRef

Класс, который можно использовать для абстракции управления разрывом. Пример использования:

val mybreaks = new Breaks
import mybreaks.{break, breakable}

breakable {
  for (...) {
    if (...) break()
  }
}

Вызовы break из одного экземпляра Breaks никогда не будут нацелены на объекты, подлежащие разрыву, в другом экземпляре.

абстрактный класс 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API