不明白如何在没有{}花键块的情况下解析多行语句

时间:2012-03-23 18:05:22

标签: scala

我遵循C系列(PHP是一个想要的!)的要求,跨越多行的语句必须包含在curlies中。

Scala避免了来自O'Reilly的Programming Scala的代码中的解析错误。

def apply(specification: String): Option[Widget] = specification match {
    case ButtonExtractorRE(label)   => new Some(new Button(label))
    case TextFieldExtractorRE(text) => new Some(new TextField(text))
    case _ => None
  }

虽然我认为它应该看起来像(函数的主体是封闭的):

def apply(specification: String): Option[Widget] = {
    specification match {
            case ButtonExtractorRE(label)   => new Some(new Button(label))
            case TextFieldExtractorRE(text) => new Some(new TextField(text))
            case _ => None
            }
    }

虽然Scala可以解析它,程序员可以“得到它”吗?我不。我错过了一些直观的想法吗?

我是否应该避免这种做法,如果它导致实际问题(如可读性差?

4 个答案:

答案 0 :(得分:3)

当你说一个函数=(没有花括号)时,它编译并正常工作,因为它是一个单独的表达式。您的“匹配”表达式始终计算为单个值。而'匹配'是你职能中唯一的东西。所以,实际上它只是一个表达式,即使它跨越几行。如果你的apply函数需要多个表达式和语句,那么是的,你需要大括号。

答案 1 :(得分:3)

在Scala中,更多内容(包括ifmatchforyield)会返回与其他语言相同的结果。而且更多的数据结构是不可变的,这通常会导致mapfilterflatMapcollect等转换链 - 这也只会产生一个结果。最后但并非最不重要的是,Scala对元组提供了极好的支持,这意味着您经常会将元组作为单个结果返回,其他语言必须对单个值进行排序。

因此,一般而言,Scala不像其他语言那样处理存储中间值的变量。这意味着函数通常只是方程f(a)= b,其中b可能非常复杂,但仍然是一个链返回单个结果。所以采用这种语法很自然,这可以立即清楚地表明你不是在处理中间结果,而是遵循更具功能性的风格。

应该提到的是,函数式语言(具有完全不同语法的“lispy”系列除外)具有类似的约定。因此,如果你看看Haskell,F#或Erlang,你通常不会看到方法的任何“块”。有letcase和(对于Haskell)do这样的结构可能看起来有点像块,但也是表达式。

答案 2 :(得分:1)

您有一个仅包含单个表达式的函数。许多语言仍然需要将它括在花括号中。

如果您只习惯使用这些语言,这可能会让您感到困惑。但是在使用Scala稍微使用单个表达式的函数定义之后,body开始看起来像一个值为'variable'的函数。

从那时起,你将不再错过花括号。

所以:在几乎所有情况下,我都会跳过我不需要的所有支撑。很长一段时间我都没有问题。

答案 3 :(得分:1)

  

我遵循C系列要求,跨越多行的语句必须包含在curlies中。

错误。

#include <iostream>
using namespace std;

int main() {
  bool b = true;
  char c = 'a';
  if (b) switch (c) {
    case 'a': cout << "It's a" << endl; break;
    default : cout << "Not a"  << endl; break;
  }
}

这里if语句的true分支跨越多行,但不包含在大括号中。事实上,你有没有使用if / else if?

if (foo) {
  // do foo stuff
else if (bar) {
  // do bar stuff
} else {
  // do non-foo/bar stuff
}

从句法上讲,else if没有特殊处理。 else只是一个常用的关键词。这语法等同于

if (foo) {
  // do foo stuff
else {
  if (bar) {
    // do bar stuff
  } else {
    // do non-foo/bar stuff
  }
}

请注意,括号不需要包围内部if。这是因为if / else语句是一个自包含的单个表达式。规则不是围绕任何跨越多行的语句。相反,我认为可以说任何以分号分隔的语句必须用大括号分组。免责声明:我不是C专家。如果您需要确定,请查看文档。

我也不是斯卡拉专家,但一般来说,我认为斯卡拉的思维方式是尽可能去除括号,当然要有良好的判断力和品味。