为什么Golang强制执行大括号不在下一行?

时间:2013-06-17 18:02:11

标签: coding-style go curly-braces

正确的:

if(true) {

}

不正确的:

if(true)
{

}

为什么这种风格被强制执行,是否与语言规范有关,还是因为他们更喜欢一种风格而不是另一种风格?

6 个答案:

答案 0 :(得分:38)

  

为什么有括号但没有分号?为什么我不能把开口支架放在下一行?

     

Go使用括号括号进行语句分组,这是一种熟悉C系列中任何语言的程序员所熟悉的语法。但是,分号用于解析器,而不是用于人,我们希望尽可能地消除它们。为了实现这个目标,Go借用了BCPL的一个技巧:分隔语句的分号在形式语法中,但是在任何可能是语句结尾的行末尾的词法分析器自动注入,而不是预测。这在实践中非常有效,但具有强制支撑样式的效果。例如,函数的左括号不能单独出现在一行上。

http://golang.org/doc/faq#semicolons

答案 1 :(得分:26)

大多数 C 下降语言使用样式if ( <condition> ) <statement>,如果statement为真,则执行conditionstatement可以是单个语句或括号括起来的块。

Go的if语句需要一个后面的大括号括号块,而不是单个语句。这是为了阻止大多数样式指南试图通过要求所有if语句都使用大括号来避免的common error

//subtle error in C
if (<condition>)
  <statement1>;
  <statement2>;

现在,Go需要if语句后面的大括号块,()是多余的。它们仅用于帮助词法分析器区分条件和语句,否则if <condition> <statement>很难解析。 (条件何时结束,声明开始?)

现在Go的作者决定:

  • 保留多余的()
  • 要求{关注<condition>

他们认为裁员是不可取的。这有第二个副作用。由于每个换行都有隐式;,如果{位于以下行,;将放在<condition>{之间。 Go的作者再次面临一个决定:

  • 特殊情况下,解析器对<condition>; {构造
  • 要聪明一些
  • 要求每个人在同一行上采用if ... {的共同风格。
  • 要求<condition>在一行上。

解析器的特殊情况是非常坏事。看看速度 D 和Go解析器与C ++糟糕的解析器性能相比。统一的风格也是一件好事。鉴于约束条件,他们的最终决定非常简单。

答案 2 :(得分:20)

我认为这种强制性的东西只是让人喜欢K&amp; R风格的借口,而不必看到Allman的风格。如果设计师喜欢Allman风格,那么他或她就会简单地让解析器处理它。 想象一下,如果XML是用K&amp; R编写的。它看起来无法理解。 Allman风格更容易阅读。 这似乎完全是一种情绪化的决定。我也会制作一个:忽略Go。

答案 3 :(得分:6)

它与Spec有关,即它不仅仅是他们在编译器中构建的东西

  

<强>分号

     

正式语法使用分号“;”作为许多人的终结者   制作。 Go程序可能会使用这些分号省略大多数这些分号   遵循两条规则:

     

当输入被分解为令牌时,如果是分号,则会在非空白行的末尾自动将分号插入到令牌流中   line的最终标记是

     
      
  • 标识符
  •   
  • 整数,浮点,虚数,符文或字符串文字
  •   
  • 其中一个关键字是break,continue,fallthrough或return
  •   
  • 其中一个运算符和分隔符++, - ,),]或}
  •   
     

要允许复杂语句占用一行,   在结束“)”或“}”之前可以省略分号。

     

为了反映惯用语,本文档中的代码示例为elide   使用这些规则的分号。

就我从谈话中抓住它而言,他们希望摆脱格式化讨论,并通过gofmt

的表达来扩展这个想法。

答案 4 :(得分:2)

因为 google 的人不喜欢 allman 风格。 但是很容易支持allman风格,forkGo(by @diyism)只在golang编译器中添加了12行代码。

试试 forkGo: https://github.com/forkgo-org/go

forkGo 支持这种 allman 风格:

package main
import
(
    "fmt"
)


func main()
{
    if false
    {   fmt.Println("jack")
        fmt.Println("forkgo")
    } else
    {   fmt/
           .Println("hello")
        fmt.Println("forkgo")
    }
}

答案 5 :(得分:0)

...“他首先要使用大括号(即,使用大括号在同一列上可以轻松识别语句块的范围),“...

同意 - 如果您想对齐大括号以区分块,这非常困难