Возможно, вы думаете о проблеме неправильно. Почему вы хотите так много вещей в своем блоке try / catch / finally? В вашем коде
try { val v = new VType() }
исключение может быть выдано , прежде чем вы получите v
обратно , поэтому вы не можете безопасно ссылаться на v
. Но если вы не можете сослаться на v
, то что вы можете сделать на стороне finally, которая не сломает, не сгенерирует свое собственное исключение или не имеет другого плохо определенного поведения? Что делать, если вы создаете v
, но не можете создать w
, но для удаления требуется также w
? (Или нет?) Это заканчивается беспорядок.
Но если вы пришли из Java, есть несколько вещей, которые могут помочь вам написать блоки try / catch / finally разумным способом.
Одна вещь, которую вы можете сделать, это перехватить определенные классы исключений и вместо этого превратить их в опции:
def s2a(s: String) = try { Some(s.toInt) } catch { case nfe: NumberFormatException => None}
Еще одна вещь, которую вы можете сделать, это создать свой собственный менеджер ресурсов
def enclosed[C <: { def close() }](c: C)(f: C => Unit) {
try { f(c) } finally { c.close() }
}
enclosed(new FileInputStream(myFile))(fis => {
fis.read...
}
Или вы можете создать свой собственный метод безопасного отключения и отключения в другом методе:
val r = valuableOpenResource()
def attempt[F](f: => F) = {
try { f } catch { case re: ReasonableException => r.close() throw re }
}
doSomethingSafe()
attempt( doSomethingDangerous() )
doSomethingElseSafe()
r.close()
Между этими различными способами обработки вещей у меня не было особой необходимости создавать переменные для хранения переменных, которые я хочу очистить позже или иным образом обрабатывать в блоках catch или finally.