繁体   English   中英

Scala try-catch-finally 表达式可以没有大括号吗?

[英]Can Scala try-catch-finally expression be without braces?

我正在学习 Scala 并且对try-catch-finally语法感到困惑。

Scala Syntax Specification 中,它说:

Expr1             ::=  ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr]
                     | ...

我可以在没有{ }块的情况下编写表达式吗:

try
  println("Hello")
catch
  RuntimeException e => println("" + e)
finally
  println("World")

或者表达式必须是块表达式?

当然。

import scala.util.control.NonFatal

def fourtyseven: PartialFunction[Throwable, Int] = {
  case NonFatal(_) => 47
}

def attempt(n: => Int): Int =
  try n catch fourtyseven finally println("done")

println(attempt(42))
println(attempt(sys.error("welp")))

这会按预期编译和运行,尽管我必须单独定义catch表达式(因为它需要大括号)。

您可以在 Scastie 上使用此代码。

一些注意事项:

  • try / catch / finally是一个返回值的表达式(如果您来自 Java,这可能有点陌生)——您可以在文档中阅读更多关于它的信息
  • catch总是从Throwable到某种类型的PartialFunctiontry / catch的整体返回类型是两者中最接近的公共超类(例如,假设你有class Animal; class Dog extends Animal; class Cat extends Animal ,如果try返回一个Dog并且catch返回一个Cat整个表达式将返回一个Animal
  • 我在catch部分函数中使用了NonFatal提取器,您可以在这个答案中阅读更多关于它的信息,而一般的提取器对象在官方文档中进行了描述

Scala 3 (Dotty) 正在试验可选的大括号(显着缩进),因此以下工作

scala> try
     |   1 / 0
     | catch
     |   case e => println(s"good catch $e")
     | finally
     |   println("Celebration dance :)")
     |
good catch java.lang.ArithmeticException: / by zero
Celebration dance :)
val res1: AnyVal = ()

我们注意到处理程序的地方

case e => println(s"good catch $e")

不需要像Scala 2那样的大括号。 事实上,由于在catch关键字之后case子句进行了特殊处理,以下也可以工作

scala> try
     |   1 / 0
     | catch
     | case e => println(s"good catch $e")
     | finally
     |   println("Celebration dance :)")
     |
good catch java.lang.ArithmeticException: / by zero
Celebration dance :)
val res2: AnyVal = ()

我们注意到处理程序在catch后不必缩进

catch
case e => println(s"good catch $e")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM