为什么Golang要求花括号不能放在下一行?

huangapple go评论70阅读模式
英文:

Why does Golang enforce curly bracket to not be on the next line?

问题

为什么要强制使用这种风格,是因为它与语言规范有关,还是只是因为他们更喜欢一种风格而已?

英文:

correct:

if(true) {

}

incorrect:

if(true)
{
    
}

Why is this style enforced, does it have something to do with the language spec, or is it just because they prefer one style over another ?

答案1

得分: 46

为什么有大括号但没有分号?为什么我不能把左大括号放在下一行?
Go语言使用大括号来进行语句分组,这是一种对于使用过C语言系列的程序员来说很熟悉的语法。然而,分号是为了解析器而不是为了人类,我们希望尽可能地减少它们的使用。为了实现这个目标,Go语言借鉴了BCPL语言的一个技巧:在正式的语法中,用于分隔语句的分号会被词法分析器自动注入,而不需要预先查看。这在实践中非常有效,但它会强制使用大括号的风格。例如,一个函数的左大括号不能单独出现在一行上。

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

英文:

>### Why are there braces but no semicolons? And why can't I put the opening brace on the next line?
>Go uses brace brackets for statement grouping, a syntax familiar to programmers who have worked with any language in the C family. Semicolons, however, are for parsers, not for people, and we wanted to eliminate them as much as possible. To achieve this goal, Go borrows a trick from BCPL: the semicolons that separate statements are in the formal grammar but are injected automatically, without lookahead, by the lexer at the end of any line that could be the end of a statement. This works very well in practice but has the effect that it forces a brace style. For instance, the opening brace of a function cannot appear on a line by itself.

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

答案2

得分: 28

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

Go的if语句需要一个后面用大括号括起来的块,而不是单个语句。这是为了避免一个常见错误,大多数风格指南都要求所有的if语句都使用大括号。

// C中的一个微妙错误
if (<condition>)
  <statement1>;
  <statement2>;

现在,由于Go要求在if语句后面跟着一个大括号块,所以()是多余的。它们只是帮助词法分析器区分条件和语句,否则if <condition> <statement>很难解析(条件在哪里结束,语句从哪里开始?)

现在Go的作者们需要做出一个决定:

  • 保留多余的()
  • 要求{跟在<condition>后面

他们决定冗余是不可取的。这带来了第二个副作用。由于每个换行符都有一个隐式的;,如果{在下一行,那么在<condition>{之间会插入一个;。Go的作者们再次面临一个决定:

  • 特殊处理解析器,使其能够智能处理<condition>; {的结构
  • 要求每个人采用相同行的if ... {的常见风格。
  • 要求<condition>在单独一行。

特殊处理解析器是一件非常糟糕的事情。看看D和Go解析器与C++糟糕的解析器性能相比。而且统一的风格是一件好事。在给定的限制条件下,他们的最终决定相当简单。

英文:

Most C descended languages use the style if ( &lt;condition&gt; ) &lt;statement&gt;, the statement is executed if condition is true. The statement can be either a single statement or brace enclosed block.

Go's if statements require a following brace enclosed block, not a single statement. This is to head off a common error that most style guides try to avoid by requiring that all if statements use braces.

//subtle error in C
if (&lt;condition&gt;)
  &lt;statement1&gt;;
  &lt;statement2&gt;;

Now that Go requires a brace block following the if statement the () are redundant. They only serve to help the lexer differentiate between the condition and the statement, otherwise if &lt;condition&gt; &lt;statement&gt; is hard to parse. (Where does the condition end and the statement begin?)

Now Go's authors have a decision to make:

  • Keep the redundant ()
  • require { to follow the &lt;condition&gt;

They decided redundancy was not desirable. This had a second side effect. Since there is an implicit ; at every newline, if the { is on the following line a ; gets put between the &lt;condition&gt; and the {. Go's authors again are faced with a decision:

  • special case the parser to be smart about the &lt;condition&gt;; { construct
  • require everyone adopt a common style of if ... { on the same line.
  • require that the &lt;condition&gt; be on a single line.

Special casing the parser is a very bad thing. Look at the speed D and Go parsers compared to C++'s terrible parser performance. Also a uniform style is a good thing. Their ultimate decision is pretty simple given the constraints.

答案3

得分: 8

这与规范有关,也就是说,这不仅仅是他们内置到编译器中的东西。

分号

正式的语法在许多产生式中使用分号“;”作为终止符号。Go程序可以使用以下两个规则省略大部分这些分号:

当输入被分解为标记时,如果行的最后一个标记是:

  • 标识符
  • 整数、浮点数、虚数、符文或字符串字面量
  • 关键字break、continue、fallthrough或return之一
  • 运算符和分隔符++、--、)、]或}

则自动在标记流的末尾插入一个分号,如果该行不是空行。

为了允许复杂语句占据一行,可以在闭合的“)”或“}”之前省略分号。

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

据我从他们的讲话中所了解的,他们想摆脱格式讨论,并通过创建gofmt来扩展这个想法。

英文:

It has to do with the Spec, i.e. it's not just something they built into their compilers
> Semicolons
>
> The formal grammar uses semicolons ";" as terminators in a number of
> productions. Go programs may omit most of these semicolons using the
> following two rules:
>
>When the input is broken into tokens, a semicolon is automatically inserted into the token stream at the end of a non-blank line if the
> line's final token is
>
> - an identifier
> - an integer, floating-point, imaginary, rune, or string literal
> - one of the keywords break, continue, fallthrough, or return
> - one of the operators and delimiters ++, --, ), ], or }
>
>To allow complex statements to occupy a single line,
>a semicolon may be omitted before a closing ")" or "}".
>
> To reflect idiomatic use, code examples in this document elide
> semicolons using these rules.

As far as I grasped it from their talks, they wanted to get rid of formatting-discussions and extended the idea with the greation of gofmt

答案4

得分: 3

因为谷歌的人不喜欢allman风格。
但是支持allman风格非常容易,forkGo(由@diyism创建)只在golang编译器中添加了12行代码。

试试forkGo:
https://gofork.org

forkGo支持这样的allman风格:

package main
import
(
    "fmt"
)


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

Because the google guys don't like allman style.
But it's very easy to support allman style, forkGo(by @diyism) only added 12 lines of code into golang compiler.

Give a try to forkGo:
https://gofork.org

forkGo support such allman style:

package main
import
(
    &quot;fmt&quot;
)


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

答案5

得分: 0

同意 - 如果你喜欢将大括号对齐以区分代码块,那么这将非常困难。

英文:

..."he point of using braces in the first place (i.e. making it easy to identify scope of statement blocks with braces lined up on same column), "...

agreed - very difficult if you like to align your braces to distinguish blocks

huangapple
  • 本文由 发表于 2013年6月18日 02:02:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/17153838.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定