Вариант использования - возможность иметь общую обработку ошибок во всем приложении. Допустим, вы хотите обработать все FileNotFoundException
в вашем приложении, отправив электронное письмо администратору. Раньше вам приходилось делать это так:
// Globally
val fileNotFound: PartialFunction[Throwable, Unit] = {
case e: FileNotFoundException =>
// Create report and send the e-mail
}
// On each try-catch-block
try {
// Open file
}
catch {
case fnf: FileNotFoundException => fileNotFound(fnf)
}
Теперь вы просто делаете:
try {
// Open file
} catch fileNotFound
Это также имеет приятное преимущество, заключающееся в том, что вы можете связать несколько таких обработчиков исключений, используя метод orElse
для частичных функций:
val fileErrors = fileNotFound orElse endOfFile orElse invalidFormat
А потом используйте это везде, где вам нужна обработка исключений файлов. Такой обработчик ошибок может быть динамически объединен, например, на основе файла конфигурации для приложения. Это гораздо менее громоздко, чем сопоставление с образцом везде и вызов правильного обработчика.
Одной полезной вещью, которую можно развернуть поверх частичных функций, является оператор andAlso
, который действует как оператор секвенирования для двух частичных функций. Это было бы полезно, если вы хотите выполнить некоторую обработку ошибок, специфичную для конкретного блока try-catch, после выполнения общей обработки ошибок.
implicit def pf2ops(pf: PartialFunction[Throwable, Unit]) = new {
def andAlso(localpf: PartialFunction[Throwable, Unit]) = new PartialFunction[Throwable, Unit] {
def apply(t: Throwable) = {
if (pf.isDefinedAt(t)) pf(t)
localpf(t)
}
def isDefinedAt(t: Throwable) = pf.isDefinedAt(t) || localpf.isDefinedAt(t)
}
}
И тогда вы можете сделать это:
scala> try {
| throw new java.io.FileNotFoundException
| } catch fnf andAlso {
| case e: Exception => println("I don't know, but something is specific to this particular block.")
| }
I don't know, but something is specific to this particular block.
Полагаю, вы могли бы продолжить играть с точной семантикой и значением (и именем) andAlso
.