Задачи на интерфесы

1) Что выведет данная программа и почему?

package main
import (
	"errors"
	"fmt"
)

const errMsg = "not found"
type myErr struct {
	msg string
}	
func (e myErr) Error() string {
	return e.msg
}
func someFunc() error {	
	return myErr{errMsg}
}
	
func main() {
	err := someFunc()
	switch {
		case err == errors.New(errMsg):
			fmt.Println("OK, next")
		case err != nil:
			fmt.Println("panic:", err.Error())
		default: // err == nil
			fmt.Println("OK, work with it")
	}		
}

Программа выведет следующее:

panic: not found

Давайте разберемся, почему это происходит:

  1. В программе определен тип ошибки myErr, который реализует интерфейс error через метод Error(), возвращающий строку сообщения об ошибке.

  2. Функция someFunc() возвращает новый экземпляр myErr с сообщением errMsg, которое равно "not found".

  3. В функции main() вызывается someFunc(), и результат (ошибка) сохраняется в переменной err.

  4. Далее следует конструкция switch без выражения, что означает, что каждый case будет проверяться на истинность в порядке их написания:

    • Первый case проверяет, равна ли ошибка err результату вызова errors.New(errMsg). Функция errors.New создает новый объект ошибки с новым адресом в памяти. Поскольку в Go сравнение ошибок происходит по идентичности (то есть по адресу в памяти), а не по содержимому, err == errors.New(errMsg) вернет false.

    • Второй case проверяет, не равна ли ошибка nil. Поскольку err содержит ошибку myErr, это условие истинно, и выполняется код внутри этого case, выводящий "panic:" и сообщение ошибки, которое равно "not found".

Таким образом, программа выводит "panic: not found", потому что ошибка err не равна nil и не равна новому экземпляру ошибки, созданному с тем же сообщением, но по другому адресу в памяти.

Last updated