英文:
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)
}
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)
}
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论