Возврат своей ошибки в Go
Функция возвращает свой тип там, где ждут
обычную ошибку. В объявлении результата
остается error, а в return
кладут указатель на свою структуру или
nil при успехе. Компилятор принимает
значение, потому что у типа есть нужный
метод текста.
Напишем чтение конфигурации, которое при
сбое отдает PathError:
package main
import (
"errors"
"fmt"
)
type PathError struct {
Path string
Err error
}
func (e *PathError) Error() string {
return e.Path + ": " + e.Err.Error()
}
func readConfig(name string) error {
return &PathError{
Path: name,
Err: errors.New("missing"),
}
}
func main() {
err := readConfig("main.go")
if err != nil {
fmt.Println(err)
}
}
Переменная err имеет интерфейсный тип
error, хотя внутри лежит *PathError.
Печать вызывает метод текста у фактического
типа. При успехе вместо структуры вернули бы
nil, и проверка err != nil
не сработала бы.
Тот же прием работает, когда ошибку создают в отдельной переменной перед возвратом:
package main
import (
"errors"
"fmt"
)
type PathError struct {
Path string
Err error
}
func (e *PathError) Error() string {
return e.Path + ": " + e.Err.Error()
}
func openFile(path string) error {
pe := &PathError{
Path: path,
Err: errors.New("locked"),
}
return pe
}
func main() {
if err := openFile("main.go"); err != nil {
fmt.Println(err)
}
}
Дан тип PathError с методом текста,
как в примере. Напишите функцию с результатом
error, которая при неудаче возвращает
PathError с путем "main.go",
и выведите ошибку из main.
Дан следующий код:
package main
import "errors"
type PathError struct {
Path string
Err error
}
func (e *PathError) Error() string {
return e.Path + ": " + e.Err.Error()
}
func load() error {
return nil
}
Измените load так, чтобы она
возвращала PathError с путем
"data.cfg", и выведите результат.
Скажите, какой результат у функции при
успешном завершении, если сигнатура
обещает error.