在 Err 上使用 Go goto 标签

问题描述

我想使用标签来最小化错误部分,如下所示:

package main
import (
    "fmt"
    consul "github.com/hashicorp/consul/api"
    "os"
)
func main(){
    client,err := consul.NewClient(consul.DefaultConfig())
    if err != nil {
        goto Err
    }
    agent := client.Agent()
    checkReg := agent.AgentCheckRegistration{
        ID:   "test-check",Name: "test-check",Notes: "some test check",}
    if err = agent.CheckRegister(checkReg); err !=nil{
        goto Err
    }
Err:
    fmt.Println(err)
    os.Exit(2)
}

所以我可以有一个地方将所有错误处理放在一个地方,但似乎不起作用

./agent.CheckRegister.go:10:8: goto Err jumps over declaration of checkReg at 
./agent.CheckRegister.go:13:19: agent.AgentCheckRegistration undefined (type *api.Agent has no field or method AgentCheckRegistration)

有没有办法使用 goto 使其工作?

解决方法

编译器报错的原因在Go spec中定义:

执行“goto”语句不能导致任何变量出现 进入在 goto 时尚未在范围内的范围。 例如,这个例子:

  goto L  // BAD  
  v := 3
L:

是错误的,因为跳转到标签 L 跳过了 v 的创建。

所以你需要重构你的代码。如果您想在此处继续使用 goto(而不是 if-else 语句),那么您必须将所有声明向上移动。

请注意,您可以像这样拆分它:

   var v Type
   ...
L: ...
   v = FunctionThatReturnsType()

在这里goto L应该没问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...