Интерфейс error

Интерфейс error является встроенным интерфейсом в Go, который используется для представления ошибок. Он имеет один метод Error() string, возвращающий строковое описание ошибки. Любой тип, реализующий этот метод, автоматически удовлетворяет интерфейсу error. Этот интерфейс широко используется в функциях, которые могут завершиться неудачей, позволяя возвращать информацию об ошибке вместе с результатом.

Синтаксис

gotype error interface {
  Error() string
}

Для создания ошибки встроенная функция errors.New создает новый объект ошибки с переданным текстом.

goerr := errors.New("something went wrong")

Пример

Давайте создадим функцию, которая возвращает ошибку при делении на ноль:

gopackage main

import (
  "errors"
  "fmt"
)

func divide(a, b int) (int, error) {
  if b == 0 {
    return 0, errors.New("division by zero")
  }
  return a / b, nil
}

func main() {
  res, err := divide(10, 0)
  if err != nil {
    fmt.Println("Error:", err.Error())
    return
  }
  fmt.Println("Result:", res)
}

Результат выполнения кода:

go"Error: division by zero"

Пример

Теперь давайте создадим собственный тип ошибки, реализующий интерфейс error:

gopackage main

import (
  "fmt"
  "strconv"
)

type ParseError struct {
  value string
}

func (e ParseError) Error() string {
  return "cannot parse value: " + e.value
}

func parseNumber(s string) (int, error) {
  num, err := strconv.Atoi(s)
  if err != nil {
    return 0, ParseError{value: s}
  }
  return num, nil
}

func main() {
  res, err := parseNumber("abc")
  if err != nil {
    fmt.Println(err.Error())
    return
  }
  fmt.Println("Parsed number:", res)
}

Результат выполнения кода:

go"cannot parse value: abc"

Пример

Использование fmt.Errorf для форматирования ошибок с дополнительной информацией:

gopackage main

import (
  "fmt"
)

func processItem(id int, name string) error {
  if id < 0 {
    return fmt.Errorf("invalid id: %d", id)
  }
  if name == "" {
    return fmt.Errorf("empty name for id %d", id)
  }
  return nil
}

func main() {
  err := processItem(-5, "test")
  if err != nil {
    fmt.Println(err.Error())
  }

  err = processItem(10, "")
  if err != nil {
    fmt.Println(err.Error())
  }
}

Результат выполнения кода:

go"invalid id: -5"
"empty name for id 10"

Смотрите также

  • интерфейс interface,
    который описывает набор методов, реализуемых типом
  • интерфейс implementation,
    который описывает реализацию интерфейса
  • интерфейс implicit-implementation,
    который описывает неявную реализацию интерфейсов
  • интерфейс fmt.Stringer,
    который используется для строкового представления типов