【问题标题】:Try/catch item with strange syntax尝试/捕获具有奇怪语法的项目
【发布时间】:2019-12-27 13:53:30
【问题描述】:

这段代码中有奇怪的语法:

var result =
  try {
     Process(bl).!!
  } catch {
    case e: Exception =>
      log.error(s"Error on query: ${hql}\n")
      "Etc etc" + "Query: " + hql
  }

为什么不在log.error(s"...") 之后使用,; 之类的分隔符?

catch 语句返回一个或两个值?

PS:有更好的Guide tham this one,具有所有 Scala 语法替代方案?

【问题讨论】:

  • 为什么要放置分隔符? - 我的意思是,语法对我来说很清楚。 catch 是一个block (类似于match。并且所有try 都必须返回一个值,在这种情况下,两个分支都返回一个String
  • 嗨 @LuisMiguelMejíaSuárez,当我使用现代 Javascript (ES6+) 时,x=>y 很明显,x=>y z 是一个错误。我没有看到“两个分支”.. Scala 语言指南说有y,z 而不仅仅是y
  • 我还是不明白你的意思? try block catch (macth expr block)+ 是 try 表达式 的语法。与该语言中的任何其他 表达式 一样,它必须返回一个值。 try expression 的返回类型是 try-block 的返回类型和所有 catch-macth-blocks 的返回类型之间的 LUB (在这种情况下只有一个,在这种情况下都返回 Strings。 - 此外,与语言中的任何其他块一样,您可以使用; 分隔语句,但如果您每行只写一个语句,它们是可选的。 - 我还是不明白为什么这会让你感到困惑。
  • @LuisMiguelMejíaSuárez 感谢正则表达式,try block catch (macth expr block)+ 这接近我正在寻找的答案,+ 让一切变得不同。在this official Guide 中有一个带有两个块的(macth expr block)+ 示例,但是您和指南没有显示我的问题的块语法。在我的问题上,我们只有一个区块,比如case foo: FooException => handleFooException(foo); handleBarException(bar),这很奇怪。
  • 并非如此,因为每个匹配项后面都有一个块。如果您想自己保持理智,可以这样做:} catch { \n case e: Exception => {\n log(...) \n "ect" \n } \n } (如果您复制和粘贴,\n 会告诉您在哪里换行,因为 cmets 不会保留它)。正如你所看到的,我们在比赛结束后开始了一个新的街区。只是,编译器允许你省略这些括号,大多数人都会这样做。

标签: scala try-catch


【解决方案1】:

Newline characters 可以终止语句

semi ::= ‘;’ | nl {nl}

Scala 是一种面向行的语言,其中的语句可以终止 用分号或换行符。 Scala 源文本中的换行符是 被视为特殊标记“nl” ...

恕我直言,换行符 \n 与分号符 ; 一样是语句终止符。但是,它可能比; 具有优势,因为它对人类是不可见的,这可能具有减少代码混乱的好处。它可能看起来很奇怪,因为它是不可见的,但请放心,它在那里默默地做着界定陈述的工作。如果我们试着想象它,也许它会变得不那么奇怪

1 + 42'\n'  // separating with invisible character \n
1 + 42;     // separating with visible character ;

注意,写multiple statements on the same line时一定要用分号

log.error(s"Error on query: ${hql}\n"); "Etc etc" + "Query: " + hql

针对评论,AFAIU,您的困惑源于对 pattern matching anonymous functionsblock expressions 工作方式的误解。脱糖处理函数

case e: Exception =>
  log.error(s"Error on query: ${hql}\n")
  "Etc etc" + "Query: " + hql

相当于

case e: Exception => {
  log.error(s"Error on query: ${hql}\n"); // side-effect statement that just logs an error
  return "Etc etc" + "Query: " + hql;     // final expression becomes the return value of the block
}

因此,“一个有两个分支的块” 不是正确的理解,而是只有一个单个代码路径通过您的特定功能。

【讨论】:

  • 感谢马里奥!好吧,你说我们是在分离命令(它相当于command1; command2),所以它不是第二个函数或方法的参数……理解这种语法的第二个问题是它分为两个分支,其中 Scala 语言导游说分店不止一个?
  • @PeterKrauss 啊,我明白你现在为什么感到困惑了,你认为catch 是一个函数。不是,它是语言内置的表达式,类似于match,都是使用模式匹配
  • @MarioGalic 是的,我的困惑就在附近......在this official Guide,我们看到了一个带有两个macth expr的例子。块,但指南没有显示我的问题的块语法。在我的问题上,我们只有一个街区,里面有两个分支,在街区内......就像case foo: FooException => {handleFooException(foo); handleBarException(bar) },这很奇怪。摘要:经过您的良好解释,我预计x=>y; x=>z not x=>(y;z)... Scala 指南在哪里说这两种语法是等价的?
猜你喜欢
  • 2012-04-17
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 2017-12-06
  • 1970-01-01
相关资源
最近更新 更多