суббота, 2 февраля 2019 г.

Эффективный Go: функция panic

Обычный способ сообщить об ошибке вызывающей стороне - вернуть error как дополнительное возвращаемое значение. Канонический метод Read является хорошо известным примером; он возвращает количество прочитанных байтов и error. Но что, если ошибка не может быть возвращена? Иногда программа просто не может продолжаться.

Для этого есть встроенная функция panic, которая в действительности создает ошибку во время выполнения (run-time error), которая остановит программу. Функция принимает один аргумент произвольного типа - часто строку - для печати в качестве сообщения о том, что программа завершается. Это также способ указать, что что-то невозможное произошло, например, выход из бесконечного цикла.

// Игрушечная реализация корня куба 
// с использованием метода Ньютона.
func CubeRoot(x float64) float64 {
    z := x/3   // Произвольное начальное значение
    for i := 0; i < 1e6; i++ {
        prevz := z
        z -= (z*z*z-x) / (3*z*z)
        if veryClose(z, prevz) {
            return z
        }
    }
    // миллион итераций не сходится; что-то не так.
    panic(fmt.Sprintf("CubeRoot(%g) did not converge", x))
}

Это только пример, но реальные библиотечные функции должны избегать panic. Если проблема может быть замаскирована или может быть сделан какой-либо обходной путь - всегда лучше позволить вещам продолжать работать, чем остановить всю программу. Один из возможных контрпримеров - во время инициализации: если библиотека действительно не может настроить себя, это может быть разумно, так сказать, паниковать.

var user = os.Getenv("USER")

func init() {
    if user == "" {
        panic("нет значения $USER")
    }
}


Читайте также:


Комментариев нет:

Отправить комментарий