Advertisement
AlexNovoross87

errors

May 12th, 2025 (edited)
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 6.92 KB | None | 0 0
  1. Обработка ошибок
  2. ----------------
  3. ->В Go нет исключений
  4. ->Ошибки возвращаются в качестве последнего значения из функции
  5. | Ошибка закодирована как часть сигнатуры функции
  6.     Просто определить, может ли функция завершиться с ошибкой
  7. | Возвращается значение nil, если ошибка не произошла
  8. ->Ошибки реализуют интерфейс error из стандартной библиотеки
  9. | Необходимо реализовать только одну функцию: Error() string
  10.  
  11. Основы
  12. ------
  13. Пакет "errors" стандартной библиотеки может генерировать простые
  14. ошибки с помощью функции New()
  15.  
  16. import "errors"
  17. func divide(lhs, rhs int) (int, error) {
  18. if rhs == 0 {
  19. return 0, errors.New("cannot divide by zero")//новая ошибка
  20. }
  21. else {
  22. return rhs / Ihs, nil }
  23. }
  24.  
  25. --------------------------------------------------------
  26.  
  27. Интерфейс Ошибок
  28. type error interface {
  29.     Error() string
  30. }
  31.  
  32. Реализация
  33. ----------
  34. //Структура ошибки деления
  35. type DivError struct { a, b int }
  36. //Реализация интерфейса Error
  37. func (d *DivError) Error() string {
  38.    return fmt.Sprintf("Cannot divide by zero: %d / %d ", d.a, d.b)
  39. }
  40.  
  41. Использование
  42. ===============
  43.  
  44. func div(a, b int) (int, error) {
  45. if b == 0 {
  46. return 0, &DivError {a, b} //структура ошибки деления
  47. } else {
  48.     return a / b, nil
  49. }
  50.  
  51. //пытаемся разделить 9 на 0
  52. answerl, err := div(9, 0)
  53.  
  54. if err != nil {
  55.   // "Cannot divide by zero: 9 / 0"
  56. fmt.Printin(err)
  57. return
  58. }
  59. fmt.Println ("The answer is:" , answerl)
  60.  
  61. }
  62.  
  63. ============================================================
  64.  
  65. Работа с ошибками
  66. ------------------
  67.  
  68.  
  69. errors.Is проверяет, соответствует ли ошибка конкретному значению ошибки
  70. (например, предопределённой sentinel-ошибке), учитывая цепочку обёрнутых ошибок.
  71.  
  72. errors.As проверяет, можно ли привести ошибку к определённому типу, и если да -
  73. присваивает её переменной нужного типа.
  74.  
  75. Подробности
  76. -----------
  77. Функция          | Что проверяет       |  Аргумент target            | Возвращает          | Пример использования
  78. ---------------------------------------------------------------------------------------------------------------------------
  79. errors.Is       |Совпадение ошибки с  |  Ошибка (error)             |true, если ошибка или  | Проверка с sentinel-ошибкой:
  80.                 |конкретным значением |                             |обёрнутая ошибка равна | errors.Is(err, ErrNotFound)
  81.                 |                     |                             |target                 |
  82. ---------------------------------------------------------------------------------------------------------------------------
  83. errors.As       |Принадлежность ошибки| Указатель на переменную     |true, если ошибка или  | Извлечение ошибки нужного
  84.                 |к конкретному типу   | ошибки нужного типа         |обёрнутая ошибка       | типа: errors.As(err, &myErr)
  85.                 |                     | (например, *MyError)        |приводится к типу      |
  86. -----------------------------------------------------------------------------------------------------------------------------
  87.                          
  88. Пример с errors.Is
  89. var ErrNotFound = errors.New("not found")
  90. if errors.Is(err, ErrNotFound) {
  91.     fmt.Println("Ошибка: не найдено")
  92. }
  93. errors.Is вернёт true, если err или любая ошибка в цепочке обёрток равна ErrNotFound.
  94.  
  95. Пример с errors.As
  96.  
  97. type MyError struct {
  98.     Code int
  99. }
  100. var myErr *MyError
  101. if errors.As(err, &myErr) {
  102.     fmt.Printf("Ошибка типа MyError с кодом %d\n", myErr.Code)
  103. }
  104. errors.As проверит, есть ли в цепочке ошибок ошибка типа *MyError, и если да - присвоит её переменной myErr.
  105.  
  106. Когда использовать
  107. Используйте errors.Is, когда хотите проверить, равна ли ошибка конкретному значению (например, sentinel-ошибке).
  108. Используйте errors.As, когда хотите проверить, принадлежит ли ошибка определённому типу, и получить доступ к её полям.
  109.  
  110. Итог
  111. errors.Is - для сравнения с конкретной ошибкой (значением).
  112. errors.As - для проверки и извлечения ошибки по типу.
  113.  
  114. Обе функции рекурсивно обходят цепочку обёрнутых ошибок, что позволяет работать с комплексными ошибками, обогащёнными контекстом.
  115.  
  116.  
  117. //определяем структуру ошибки
  118. type UserError struct {
  119. Msg string
  120. }
  121.  
  122. //определяем для нее Error
  123. func (u *UserError) Error() string {
  124.     return fmt Sprintf( User error: %string(u.Msg))
  125. }
  126. //выполняем какую-то функцию
  127. _, err := someFunc( sample")
  128.  
  129. if err != nil
  130. {
  131.   var InputError = UserError{"Input Error"}
  132.   if errors.Is(err, &InputError)
  133.   {
  134.    fmt.Printin("Input error:", err)
  135.   } else {
  136.    fmt.Println(’Other error:", err)
  137.     }
  138. }
  139.  
  140.  
  141. //выполняем какую-то функцию
  142. _, err := someFunc( sample")
  143.  
  144. if err != nil
  145. {
  146.   var this_error = UserError *
  147.   //Если err имеет тип UserError
  148.   if errors.As(err, this_error)
  149.   {
  150.    fmt.Printin("Input error:", err)
  151.   } else {
  152.    fmt.Println(’Other error:", err)
  153.     }
  154. }
  155.  
  156.  
  157. func main() {
  158.  
  159.     // Создаём ошибку типа *UserError
  160.     use := &UserError{Msg: "ERROR"}
  161.  
  162.     // Объявляем переменную для поиска ошибки типа *UserError1
  163.     var ue *UserError1
  164.  
  165.     // Пробуем привести ошибку use к типу *UserError1
  166.     if errors.As(use, &ue) {
  167.         fmt.Println("The Same AS")
  168.     } else {
  169.         fmt.Println("Not The Same AS")
  170.     }
  171.  
  172.     // Пример с ошибкой того же типа
  173.     var ue2 *UserError
  174.     if errors.As(use, &ue2) {
  175.         fmt.Println("This is UserError:", ue2.Msg)
  176.     }
  177.  
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement