#go #label #goto
#Вперед #метка #goto
Вопрос:
Я хочу использовать label для минимизации ошибок, подобных этой:
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, чтобы заставить его работать?
Комментарии:
1. Нет, ошибка объясняет, почему. Предварительно проясните все, используйте условные блоки или функцию, в которую вы можете вернуться раньше
2. @JimB хорошо, спасибо.
Ответ №1:
Причина, по которой компилятор жалуется, определена в спецификации Go:
Выполнение инструкции «goto» не должно приводить к попаданию в область видимости каких-либо переменных, которые еще не были в области видимости в момент перехода. Например, этот пример:
goto L // BAD v := 3 L:
ошибочно, потому что переход к метке L пропускает создание v.
Поэтому вам нужно будет реструктурировать свой код. Если вы хотите продолжать использовать goto
here (в отличие, скажем, if-else
от statements ), вам придется переместить все объявления вверх.
Обратите внимание, что вы можете разделить его следующим образом:
var v Type
...
L: ...
v = FunctionThatReturnsType()
Здесь все должно быть в порядке goto L
.