为什么在 if 条件中添加括号会导致编译错误?

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

Why does adding parentheses in if condition results in compile error?

问题

以下是翻译好的内容:

以下的Go代码可以正常运行:

package main

import "fmt"

func main() {
    if j := 9; j > 0 {
        fmt.Println(j)
    }
}

但是在条件语句中添加括号后:

package main

import "fmt"

func main() {
    if (j := 9; j > 0) {
        fmt.Println(j)
    }
}

会出现编译错误:

.\Hello.go:7: syntax error: unexpected :=, expecting )
.\Hello.go:11: syntax error: unexpected }

为什么编译器会报错呢?

英文:

The following Go code runs OK:

package main

import "fmt"

func main() {
	if j := 9; j > 0 {
		fmt.Println(j)
	}
}

But after adding parentheses in condition:

package main

import "fmt"

func main() {
	if (j := 9; j > 0) {
		fmt.Println(j)
	}
}

There is compile error:

.\Hello.go:7: syntax error: unexpected :=, expecting )
.\Hello.go:11: syntax error: unexpected }

Why does the compiler complain about it?

答案1

得分: 11

答案并不简单地是“因为Go语言不需要括号”,请看下面的示例,它是一个有效的Go语法:

j := 9
if (j > 0) {
    fmt.Println(j)
}

Go语言规范:If语句

IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .

我的示例与你的示例的区别在于,我的示例只包含了Expression块。你可以根据需要给表达式加上括号(尽管格式可能不正确,但这是另一个问题)。

在你的示例中,你同时指定了Simple语句和Expression块。如果你将整个内容放在括号中,编译器将尝试将整个内容解释为不符合条件的Expression块

Expression = UnaryExpr | Expression binary_op UnaryExpr .

j > 0 是一个有效的表达式,j := 9; j > 0 不是一个有效的表达式。

甚至 j := 9 本身也不是一个表达式,它是一个短变量声明。此外,简单赋值(例如 j = 9)在Go语言中不是一个表达式,而是一个语句(规范:赋值语句)。请注意,在其他语言如C、Java等中,赋值通常是一个表达式。这就是为什么下面的代码也是无效的原因:

x := 3
y := (x = 4)
英文:

The answer is not simply "because Go doesn't need parentheses"; see that the following example is a valid Go syntax:

j := 9
if (j > 0) {
	fmt.Println(j)
}

Go Spec: If statements:

IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .

The difference between my example and yours is that my example only contains the Expression block. Expressions can be parenthesized as you want to (it will not be well formatted, but that is another question).

In your example you specified both the Simple statement and the Expression block. If you put the whole into parentheses, the compiler will try to interpret the whole as the Expression Block to which this does not qualify:

Expression = UnaryExpr | Expression binary_op UnaryExpr .

j > 0 is a valid expression, j := 9; j > 0 is not a valid expression.

Even j := 9 in itself is not an expression, it is a Short variable declaration. Moreover the simple assignment (e.g. j = 9) is not an expression in Go but a statement (Spec: Assignments). Note that assignment is usually an expression in other languages like C, Java etc.). This is the reason why for example the following code is also invalid:

x := 3
y := (x = 4)

答案2

得分: 3

因为这是Go语法中定义if语句的方式。

> IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt |
> Block ) ] .

并且根据Effective Go

> 括号
>
> Go语言需要的括号比C和Java少:控制结构(if、for、switch)在语法中不需要括号。

还有:

> 控制结构
>
> Go语言的控制结构与C语言类似,但在重要方面有所不同。它没有do或while循环,只有一个稍微通用的for循环;switch更加灵活;if和switch接受一个可选的初始化语句,就像for循环一样;break和continue语句可以带有可选的标签,用于标识要中断或继续的位置;还有一些新的控制结构,包括类型switch和多路通信多路复用器select。语法也略有不同:没有括号,主体必须始终用大括号括起来。

(强调部分)

英文:

Because that is how the Go syntax defines an if statement.

> IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt |
> Block ) ] .

And from Effective Go:

> Parentheses
>
> Go needs fewer parentheses than C and Java: control
> structures (if, for, switch) do not have parentheses in their syntax.

and:

> Control structures
>
> The control structures of Go are related to those of C but differ in
> important ways. There is no do or while loop, only a slightly
> generalized for; switch is more flexible; if and switch accept an
> optional initialization statement like that of for; break and continue
> statements take an optional label to identify what to break or
> continue; and there are new control structures including a type switch
> and a multiway communications multiplexer, select. The syntax is also
> slightly different: there are no parentheses and the bodies must
> always be brace-delimited.

(Emphasis added)

huangapple
  • 本文由 发表于 2015年6月19日 11:29:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/30929477.html
匿名

发表评论

匿名网友

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

确定