Обработка исключений при некорректном вводе — КиберПедия 

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Обработка исключений при некорректном вводе

2022-09-29 32
Обработка исключений при некорректном вводе 0.00 из 5.00 0 оценок
Заказать работу

Конечно, здорово собрать внешний ввод для вашей программы, но иногда эти входные данные могут создавать новые проблемы. Вы,
наверное, знаете слоган "Мусор внутрь, мусор наружу": неправильный ввод может испортить всю дальнейшую обработку. Пользуясь нашим предыдущим примером, предположим, что пользователь вводит строку, такую как "abc", когда программа ожидает целое число; иначе говоря, строку, которая не может быть преобразована в целое число. Что
случится тогда?

Что-то ужасное: ошибка во время выполнения или исключительная ситуация (ЧП). Как и профессиональным программистам, вам надлежит избегать этого любой ценой.

  <= Invalid Int8: abc (ArgumentError)

 0x451477: *CallStack::unwind:Array(Pointer(Void)) at??

0x465a92: to_i8 at /opt/crystal/src/string.cr 358:5

...

Вы всегда должны остерегаться «опасного» ввода. Лучший способ управиться с этим — сделать простой тест "to_i8?", чтобы увидеть, начинается ли строка с допустимого числа. Если нет, тестовая про-
верка возвращает ноль (nil):

  if num.to_i8?

arr << num.to_i8

else

puts "Input is not an integer."

  end

Теперь вы получите замечательное сообщение об ошибке, и никаких отказов во время выполнения! (Как и в Ruby, в Crystal есть соглашение,
что методы с именами, оканчивающимися на "?", возвращают ноль (nil), если ничего не найдено.) Если ошибочность такова, что вам желательно остановить программу с помощью собственного сообщения об ошибке, используйте "raise":

  if num.to_i8?

arr << num.to_i8

else

raise "Input is not an integer."

  end

 

Применение этой техники к нашему конвертеру валют дает нам следующее:

types_and_control_flow/curr_conv2.cr

if rate.to_f?

rates[curr] = rate.to_f

else

puts "rate is no decimal number"

  end

 

Используя элементарный "puts", эту программу не остановить. Альтернативой будет использование begin-rescue, механизма для обработки исключительных ситуаций:

 

types_and_control_flow/getting_input_exception.cr

puts "Enter the numbers one by one, and end with an empty line:"

  arr = [] of Int8

while number = gets

number = number.strip # removes leading or trailing whitespace

if number == "" || number == "stop"

break

  end

begin

arr << number.to_i8

rescue

puts "integer bigger than 255"

  end

 end

p arr # => for example: [78, 56, 12]

 

Инструкция rescue предвосхищает стандартную обработку исклю­чительных ситуаций, так что программа не завершится аварийным отказом.

Выполнение обработчика исключений, подобного этому, влечет за
собой резервирование оперативной памяти, и обычно это происходит медленно, как в ЯП Java или Ruby. Вам лучше попытаться избежать
этого с помощью простых тестов, таких как "to_i?" или даже "to_f?",
если возможно.

Если вам действительно необходимо использовать begin-rescue, минимизируйте количество кода между begin и rescue, чтобы избе-
жать и чрезмерного потребления памяти, и потенциально сложной логики. Используйте исключения только для исключительных слу-
чаев, но не для ожидаемых событий!

Как и в Ruby, этот механизм может также иметь ветви "else" и
"ensure". И в rescue вы можете использовать объект исключения "ex":

 

  begin

  # some dangerous code here

  # possibly your own raise "..."

rescue ex

  # execute if an exception is raised

p ex.message

else

  # execute if an exception isn't raised

ensure

  # this will always be executed

puts "Cleanup..."

end

 

Сцепливание методов

По-видимому, вам нравится красивый код — в противном случае вы
бы не продолжали чтение этой книги. Преобразование данных часто требует предсказуемой последовательности методов. Одна из прелестей языка Crystal в том, что вы можете соединять несколько методов в
цепочку для создания более удобочитаемого кода. Метод может быть вызван для любого объекта, относительно которого он определен, и этот объект может быть результатом другого вызова какого-то метода.

Взгляните на следующие примеры:

types_and_control_flow/chaining.cr

 result = (42..47).to_a # => [42, 43, 44, 45, 46, 47]          (1)

 .sort { |n, m| m <=> n } # => [47, 46, 45, 44, 43, 42]     (2)

 .reject { |n| n.odd? } # => [46, 44, 42]                     (3)

 .map { |n| n * n } # => [2116, 1936, 1764]                  (4)

 .select { |n| n % 4 == 0 } # => [2116, 1936, 1764]            (5)

 .tap { |arr| puts "#{arr.inspect}" } # => [2116, 1936, 1764]       (6)

 .sort! # => [1764, 1936, 2116]                                       (7)

 .any? { |num| num > 2000 } # => true                                (8)

 

 1) Диапазон преобразуется в массив с "to_a".

 2) Массив сортируется в обратном порядке (< = > это оператор сравнения).

 3) Все нечетные числа исключаются с помощью "reject".

 4) Функция "map" принимает другую функцию в качестве аргумента, чтобы возвести все элементы в квадрат.

 5) Выбираются все числа, делящиеся на 4.

 6) Метод "tap" касание передает объект в блок и возвращает его — полезно для отладки или сжатия кода.

 7) Массив сортирует себя.

 8) Проверка функцией "any?" содержит ли массив число больше 2000.

 

 

Вы также имеете в своем распоряжении "reduce", который накапливает результат выполнения вычислений над элементами коллекции, в приведенном ниже случае — сумму (sum) всех чисел массива arr:

types_and_control_flow/chaining.cr

sum = (42..47).to_a

.reduce(0) { |sum, num| sum + num }

# => 267 (= 42 + 43 +... + 47)

Метод reduce привносит функциональный подход в математические вычисления, производимые в Crystal.

Вы можете именовать свои методы в той самой манере, характерной для ЯП Ruby:

• Методы, которые заканчиваются на "!" (вроде sort!), по условию изменяют объект, для которого они вызваны. (Обычно метод "pp!" показывает более полное выражение, чем "pp".)

• Методы, которые заканчиваются на "?" (такие как any?), задают логический вопрос и возвращают true или false.

 


Поделиться с друзьями:

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.006 с.