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

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 }

为什么编译器会抱怨它?

因为这就是 Go 语法 definesif 语句的方式。

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

来自 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.

(强调)

答案并不简单"because Go doesn't need parentheses";看到下面的例子是一个有效的 Go 语法:

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

Go Spec: If statements:

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

我的例子和你的例子的区别在于我的例子只包含表达式块。表达式可以根据需要加上括号(它不会被格式化,但这是另一个问题)。

在您的示例中,您同时指定了 Simple 语句和 Expression 块。如果将整体放在括号中,编译器将尝试将整体解释为 Expression Block to which this does not qualify:

Expression = UnaryExpr | Expression binary_op UnaryExpr .

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

甚至j := 9本身也不是一个表达式,它是一个Short variable declaration. Moreover the simple assignment (e.g. j = 9) is not an expression in Go but a statement (Spec: Assignments)。请注意,赋值通常是其他语言(如 C、Java 等)中的表达式)。这就是为什么例如以下代码也无效的原因:

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