Українська
Логічні помилки та коди завершення
Приклад 4. Логічна помилка середнього
Потрібно усереднити додатні значення масиву. Якщо суму додатних поділити на довжину всього масиву, нульові й від’ємні значення помилково вплинуть на знаменник. Винятку може не бути, але результат буде неправильним.
kotlin
fun positiveAverage(values: IntArray): Double? {
var sum = 0L
var count = 0
for (value in values) {
if (value > 0) {
sum += value
count++
}
}
return if (count == 0) null else sum.toDouble() / count
}
fun main() {
val values = intArrayOf(10, -5, 20)
println(positiveAverage(values))
println(positiveAverage(intArrayOf(-2, 0)))
check(positiveAverage(values) == 15.0)
check(positiveAverage(intArrayOf()) == null)
}Результат: 15.0, потім null. Масив тут використано як невеликий фіксований набір для відтворення помилки; загальні колекції розглядаються в темі 10. Long для суми зменшує ризик переповнення проміжного Int.
Поставте точку перед return. Для першого масиву значення sum має бути 30, count –2, а values.size –3. Обчисліть обидва вирази в Evaluate Expression: sum.toDouble()/count і sum.toDouble()/values.size. Порівняння показує причину, а не лише неправильний підсумок.
Знімок екрана
Evaluate both average expressions for[10,-5,20]; show15.0 versus10.0.
Рис. 4.11. Порівняння правильного й помилкового знаменника
Вирази в налагоджувачі можуть виконувати методи та змінювати стан. Не запускайте в них списання, видалення або мережеві операції заради перегляду. Спостерігайте за чистими обчисленнями й локальними даними.
Коди завершення та межа застосунку
Консольний застосунок має чітко відрізняти успіх і неправильний ввід. Домовимося про код 0 для успіху та 2 для помилки користувача. Предметна функція не повинна викликати exitProcess; вона повертає значення або кидає описаний виняток. Межа CLI перекладає цей результат у текст, stderr і код завершення.
exitProcess негайно завершує процес; не розраховуйте, що він розкрутить стек і виконає всі блоки finally. Спочатку закрийте ресурси або поверніться з функції, яка ними володіє, і лише потім завершуйте програму потрібним кодом.
Коректна обробка не повинна друкувати успішний підсумок після повідомлення про помилку. Для операцій зі станом перевірте, що стан не змінився. Для повторного вводу встановіть зрозумілу умову завершення, зокрема кінець потоку, щоб не створити нескінченний цикл запитів.
Підсумкова перевірка
Для кожної операції визначте нормальний вхід, порушену передумову, очікуваний тип помилки та стан після неї. Перевірте не лише текст, а й відсутність часткової зміни. Після виправлення логічної помилки залиште автоматичну перевірку, яка відтворює саме знайдений випадок.
Джерела: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/run-catching.html, https://www.jetbrains.com/help/idea/debugging-code.html, https://www.jetbrains.com/help/idea/using-breakpoints.html.