Как исправить проблему деления на ноль в решении задачи
Что проверяют
Замечаете ли вы граничные случаи в своём решении и знаете ли, как деление на ноль ведёт себя в Kotlin для разных типов. Обычно вопрос звучит после лайвкодинга: «а если список пустой?», и дальше интересует, что должна вернуть функция в этом случае.
Как отвечать
Сначала поведение языка, потому что оно разное:
- целые числа:
IntиLongпри делении и при%на ноль бросаютArithmeticException, приложение упадёт, если исключение не поймать; - числа с плавающей точкой:
DoubleиFloatне бросают ничего.1.0 / 0даётInfinity,0.0 / 0даётNaN, и это значение тихо едет дальше; - стандартная библиотека:
emptyList<Int>().average()возвращаетNaN, а не ноль и не исключение.
Потом найдите, откуда в задаче берётся ноль: пустой массив, нулевая длина, total у прогресса загрузки, ширина view до первого layout. Исправление начинается не с if, а с решения, какой контракт у функции при пустых данных:
- явная проверка на входе:
if (count == 0) return 0годится, только если ноль в ответе ничем не отличается от «данных нет»; - nullable или результат-обёртка:
fun average(items: List<Int>): Double?заставляет вызывающий код обработать пустой случай, например показать пустое состояние экрана; require(count > 0): если ноль означает ошибку программиста, падайте громко сIllegalArgumentExceptionи понятным сообщением;- проверка результата: для дробных вычислений
result.isFinite()отсекает иNaN, и бесконечности.
Завершите юнит-тестом на граничные значения: пустой список, один элемент, ноль в делителе.
Где спотыкаются
Оборачивают деление в try { } catch (e: Exception). Исключение как ветка логики маскирует реальные ошибки, а для Double оно всё равно не сработает.
Проверяют только Int, забывая про плавающую точку. NaN доезжает до UI и превращается в «NaN%» на экране или в сломанную отрисовку, если попадает в размер или alpha у view.
Молча возвращают ноль там, где ноль это валидное значение. Пользователь видит «0% выполнено» вместо сообщения, что задач пока нет, и баг уже продуктовый, а не технический.