Проблема с попыткой-наконец-то в Scala

#scala #exception

#scala #исключение

Вопрос:

У меня есть следующий код scala:

 val file = new FileReader("myfile.txt")
try {
 // do operations on file
} finally {
  file.close() // close the file
}
 

Как мне обработать исключение FileNotFoundException, возникающее при чтении файла? Если я помещу эту строку внутри блока try, я не смогу получить доступ к переменной file внутри finally.

Комментарии:

1. scala-lang.org/api/current/scala/util/Using $.html

Ответ №1:

Для scala 2.13: вы можете просто использовать Using для получения некоторого ресурса, и release это автоматически без обработки ошибок, если это AutoClosable :

 import java.io.FileReader
import scala.util.Using

val newStyle: Try[String] = Using(new FileReader("myfile.txt")) { 
  reader: FileReader =>
    // do something with reader
    "something"
}
newStyle
// will be 
// Failure(java.io.FileNotFoundException: myfile.txt (No such file or directory))
// if file is not found or Success with some value it will not fall
 

scala 2.12:

Вы можете обернуть свое творение reader scala.util.Try , и если оно попадет на creation, вы получите Failure FileNotFoundException inside.

 import java.io.FileReader
import scala.util.Try

val oldStyle: Try[String] = Try{
  val file = new FileReader("myfile.txt")
  try {
    // do operations on file
    "something"
  } finally {
    file.close() // close the file
  }
}
oldStyle
// will be 
// Failure(java.io.FileNotFoundException: myfile.txt (No such file or directory))
// or Success with your result of file reading inside
 

Я рекомендую не использовать try ... catch блоки в коде scala. В некоторых случаях это не обеспечивает безопасность типов и может привести к неочевидным результатам, но для освобождения некоторого ресурса в старых версиях scala есть единственный способ сделать это — использовать try finally .

Комментарии:

1. Вы можете использовать Try для освобождения ресурсов, вы также можете использовать соответствующие типы данных управления ресурсами, такие как cats.effect.Resource или zio.ZManaged .