go - 混合:= and = in Go if statements

标签 go

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 的第一个子句中设置一个变量,测试错误,如果没有错误,则继续程序的其余部分flow(并且能够使用您在执行 if 时分配的任何值)。但是,在我看来,如果你想这样做,你必须:

  1. 使用临时变量,然后在 else 内分配持久变量值:

    var val
    
    if tempval, err := func(); err != nil {
        /* Process the error */
    } else {
        val = tempval
    }
    
  2. 声明 err 变量,其范围超出 if,如上所示。

第一个选项似乎很笨重 - 被迫使用“else”子句只是为了确保值不会超出范围 - 而第二个选项则放弃了限制变量范围的优势。对于这种(看似很常见)的情况,更有经验的 Go 程序员会使用哪些惯用语?

最佳答案

The Go Programming Language Specification

If statements

"If" statements specify the conditional execution of two branches according to the value of a boolean expression. If the expression evaluates to true, the "if" branch is executed, otherwise, if present, the "else" branch is executed.

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

.

if x > max {
  x = max
}

The expression may be preceded by a simple statement, which executes before the expression is evaluated.

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

Blocks

Declarations and scope

因此,你可以这样写

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

关于go - 混合:= and = in Go if statements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213208/

相关文章:

文件扫描器循环不执行

function - 如何在 Golang 中编写一个将多种类型作为参数的函数?

mysql - sql : Scan error on column index 6, 名称 "scheduled_date": null: cannot scan type []uint8 into null. 时间

go - 在 go 中轮询函数直到 ok != true 的惯用方式

go - fmt.Sprint() 返回不正确的结果

json - 在 Go 中通过嵌入式结构实现 json 编码器

去 : model ( or interface ) function with input of different types

json - Go : When will json. Unmarshal to struct 返回错误?

高语 : Allocating Slice of Slices in functions results in index out of range

go - 如何在没有代码重复的情况下初始化映射?