На этом шаге рассмотрим пример обработки исключений в Go.
Глубоко в недрах пакета имеется функция, которую можно использовать, но нельзя изменить, потому что она входит в состав стороннего пакета, неподконтроль ного нам.
/*функция преобразует значение типа int64 в значение типа int или возбуждает аварийную ситуацию, если преобразование может дать неверный результат*/ func ConvertInt64ToInt(x int64 ) int { if math.MinInt32 <= x && x <= math.MaxInt32 { return int(x) } panic(fmt.Sprintf("%d выходит за пределы диапазона Int32", x)) }
Внутри пакетов, где вызывается функция panic(), общепринято использовать функцию recover(), чтобы за границы пакета аварии попадали только в виде значений типа error.
Следует избегать возбуждения аварийных ситуаций и при появлении проблем возвращать непустое значение ошибки. В данном примере в случае успешного преобразования требуется вернуть значение типа int и nil и значения типа int и error, если преобразование потерпело неудачу. Ниже представлена функция-обертка, позволяющая достигнуть желаемого эффекта:
func IntFromInt64(x int64) (i int, err error) { defer func () { if e := recover(); e != nil { err = fmt.Errorf("%v", e) } }() i = ConvertInt64ToInt(x) return i, nil }
В момент вызова этой функции возвращаемые значения будут инициализированы нулевыми значениями в соответствии с их типами, в данном случае 0 и nil. Если вызванная функция ConvertInt64ToInt() вернет управление как обычно, результат преобразования будет присвоен возвращаемому значению i, и вызывающей программе будет возвращено значение i и nil в качестве ошибки. Но если функция ConvertInt64ToInt() возбудит аварийную ситуацию, она будет перехвачена отложенным вызовом анонимной функции, и возвращаемому значению err будет присвоена ошибка с текстом, извлеченным из текстового представления аварийной ситуации.
На следующем шаге рассмотрим пользовательские функции в Go.