Как упомянуто @HristoIliev, ваш метод не может быть хвостовой рекурсией, поскольку finally
вызов не гарантируется хвост вызова. Это означает, что любой метод, использующий try
таким образом, не будет хвостом рекурсивным. См. Также this answer.
Вызов метода снова - это странный способ многократно повторять попытку, пока он не преуспеет, потому что на каждом этапе он бросает исключение, которое вы, по-видимому, не обрабатываете. Вместо этого я бы сказал, используя функциональный подход с Try
, принимая неудачи с точки зрения, пока операция не завершится успешно. Единственным недостатком этого подхода является то, что он не бросает никаких исключений для вас, чтобы вы могли справиться на этом пути (что также может быть преимуществом!).
def tryAll[A](xs: List[A])(f: A => Unit): Unit =
xs.view.map(x => Try(f(x))).takeWhile(_.isFailure).force
scala> val list = List(0, 0, 0, 4, 5, 0)
scala> tryAll(list)(a => println(10/a))
2
Если вы действительно хотите обрабатывать исключения (или только последнее исключение), вы можете изменить тип возвращаемого tryAll
к List[Try[Unit]]
(или просто Try[Unit]
, если изменить код только взять последний). Для возвращаемого типа метода лучше описать часть того, что он на самом деле делает - потенциально возвращающие ошибки.
Функция не является хвостовой рекурсивной, поскольку в случае, когда исключение получает бросок, блок 'finally' не является последним кодом для выполнения. –
@HristoIliev: Я вижу - как я могу написать это эффективным и идиоматическим образом? – pathikrit
Я считаю, что идиоматическим способом было бы использовать 'scala.util.Try', чтобы обернуть вызовы функций, но я не могу предоставить вам пример кода. –