Обичайно1 в Го грешките се съобщават изрично чрез връщане на отделна сойност. Това е съвсем различен подход в сравнение с езици като Java, Python и Ruby и презареденият2 единичен изход3 / грешка, ползван понякога в C.
С този подход Го прави по-лесно да се видят функциите, които връщат грешки и да се обработват грешките по същия начин както и другите стойности, ползвани за други задачи.
Вижте документацията на пакета
errors и тази
статия за повече
подробности.
import (
"errors"
"fmt"
)
Обичайно1 грешките са последната върната
стойност и са от вида error, който е описано и
осъществено в пакета взаимодействие.
func f(arg int) (int, error) {
if arg == 42 {
errors.New съставя обикновена стойност от
вида error с дадено съобщение за грешка.
return -1, errors.New("не мога да работя с 42")
}
Стойност nil на мястото на грешката означава, че
няма грешка.
return arg + 3, nil
}
Предпазната грешка1 представлява предварително обявена променлива, която се използва, за да обозначи грешка, случила се при определени условия.
var ErrOutOfTea = errors.New("няма повече чай")
var ErrPower = errors.New("не мога да сваря вода")
func makeTea(arg int) error {
if arg == 2 {
return ErrOutOfTea
} else if arg == 4 {
Можем да обгърнем1 грешките в други грешки от по-високо
равнище, за да добавим смисъл2. Най-простият начин да го
направим е с помощта на глагола %w в fmt.Errorf. Обгърнатите
грешки създават смислова логическа верига (А обгръща Б, която
обгръща В, и т.н.), която може да бъде проследявана с функции като
errors.Is и errors.AsType.
return fmt.Errorf("правя чай: %w", ErrPower)
}
return nil
}
func main() {
for _, i := range []int{7, 42} {
В Го обичайно се прави проверка направо в
реда с условието – след if
if r, e := f(i); e != nil {
fmt.Println("f не проработи:", e)
} else {
fmt.Println("f проработи:", r)
}
}
for i := range 5 {
if err := makeTea(i); err != nil {
errors.Is проверява дали дадена грешка (или всяка грешка по веригата ѝ) съвпада с опредлена стойсност. Това е особено полезно при обгърнати или вгнездени една в друга грешки и ви позволява да разпознаете определени видове грешки или предпазни грешки по веригата.
if errors.Is(err, ErrOutOfTea) {
fmt.Println("Трябва да си купим чай!")
} else if errors.Is(err, ErrPower) {
fmt.Println("Сега е тъмно.")
} else {
fmt.Printf("непозната грешка: %s\n", err)
}
continue
}
fmt.Println("Чаят е готов!")
}
}
$ go run errors.go
f проработи: 10
f не проработи: не мога да работя с 42
Чаят е готов!
Чаят е готов!
Трябва да си купим чай!
Чаят е готов!
Сега е тъмно.
Следващ пример: Съставени Грешки.