【问题标题】:Why does adding parentheses in if condition results in compile error?为什么在 if 条件中添加括号会导致编译错误?
【发布时间】:2015-06-19 03:29:28
【问题描述】:

以下 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 }

为什么编译器会抱怨它?

【问题讨论】:

  • 如果省略括号,为什么 C 编译器会报错?

标签: syntax go syntax-error


【解决方案1】:

答案不仅仅是“因为 Go 不需要括号”;看到下面的例子是一个有效的 Go 语法:

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

Go Spec: If statements:

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

我的示例和您的示例之间的区别在于我的示例仅包含 Expression 块。表达式可以根据需要加括号(格式不好,但这是另一个问题)。

在您的示例中,您指定了 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。此外,简单的赋值(例如j = 9)在 Go 中不是一个表达式,而是一个语句(Spec: Assignments)。请注意,赋值通常是其他语言(如 C、Java 等)中的表达式)。这就是为什么例如以下代码也是无效的原因:

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

【讨论】:

  • 你仍然可以写if j := 9; (j > 0) { fmt.Println(j) }
【解决方案2】:

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

IfStmt = "如果" [ SimpleStmt ";" ] 表达式块 [ "else" ( IfStmt | 块 ) ] .

来自Effective Go

括号

Go 比 C 和 Java 需要更少的括号:控制 结构(if、for、switch)的语法中没有括号。

and:

控制结构

Go 的控制结构与 C 的控制结构相关,但不同之处在于 重要途径。没有 do 或 while 循环,只有一个略 概括为;切换更灵活; if 和 switch 接受一个 可选的初始化语句,如 for;中断并继续 语句采用可选标签来标识要中断的内容或 继续;并且有新的控制结构,包括类型开关 和一个多路通信多路复用器,选择。 语法也是 略有不同:没有括号,正文必须 总是用大括号分隔。

(已添加重点)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    相关资源
    最近更新 更多