Go有一个常见的习语,如下所示:
if val, err := func(); err != nil {
/* val and err are in scope */
...
}
/* val and err are no longer in scope */
使用"短作业"。我当然是粉丝。感觉类似于:
/* code not involving val */
{
int val;
if ((val = func()) == ERR_VALUE) {
/* Process the error */
}
/* Do something with val */
}
/* more code not involving val */
在C ++中。让我感到震惊的是,在if的第一个条款中有多个变量的情况下,它们必须具有相同的范围,即你必须这样做:
var err error
var val string
if val, err = func(); err != nil {
...
或
if val, err := func(); err != nil {
...
一个非常常见的用例似乎是你有一个变量,你想在if的第一个子句中设置,测试错误,如果没有,继续其余的程序流程(并且能够使用您在执行if时指定的任何值)。但是,在我看来,如果你想这样做,你必须要么:
使用临时变量,然后在else中分配持久变量值:
var val
if tempval, err := func(); err != nil {
/* Process the error */
} else {
val = tempval
}
声明err变量,其范围超出if,如上所述。
第一种选择似乎很笨拙 - 被迫使用"否则"条款只是为了确保值不会超出范围 - 第二个条款抛弃了限制变量范围的优点。哪些成语更有经验的Go程序员用于此(看似非常常见)的情况?
答案 0 :(得分:4)
The Go Programming Language Specification
"如果"语句指定两个分支的条件执行 根据布尔表达式的值。如果表达 评估为真,"如果"执行分支,否则,如果存在, "其他"分支被执行。
IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
if x > max { x = max }
表达式可以在一个简单的语句之前执行 在评估表达式之前。
if x := f(); x < y { return x } else if x > z { return z } else { return y }
如果您无法利用特殊表格,
if val, err := fnc(); err != nil {
// ...
}
然后使用常规表单
val, err := fnc()
if err != nil {
// ...
}
常规表格是Go语言必需和通常的形式。为方便起见,特殊形式是一种特殊形式的常规形式;没有必要。如果特殊表格比常规表格更方便使用,请使用它。否则,请使用常规表格。
Go是block-structured programming language追溯它的祖先,回到Algol 60,C,Pascal,Modula 2和Oberon。
The Go Programming Language Specification
因此,你可以写
x := false
{
x := true
if x {
fmt.Println(x)
}
}
fmt.Println(x)
或者,等同于方便,
x := false
if x := true; x {
fmt.Println(x)
}
fmt.Println(x)
两种情况下的输出都是
true
false