Использование укороченного синтаксиса для обработки исключений — КиберПедия 

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Использование укороченного синтаксиса для обработки исключений

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

Помните, как мы получали пользовательский ввод данных, заполняли ими массив и предотвращали вероятную исключительную ситуацию с помощью "begin/rescue" в параграфе "Обработка пользовательского ввода"? Вы можете написать такой код гораздо более лаконично. Во-первых, давайте перепишем этот код, используя несколько методов,
чтобы сделать его более структурным:

methods_and_procs/exceptions.cr

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

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

 

def input_array

arr = [] of Int8

while number = gets

number = number.strip  # removes leading or trailing whitespace

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

break

end

add_to_array(arr, number)

end

arr

end

 

def add_to_array(arr, number)

begin

arr << number.to_i8

rescue

puts "integer bigger than 255"

end

end

Теперь метод "add_to_array" обрабатывает потенциально возможное исключение (exception). Вы можете написать это более сжато, отбросив ключевое слово begin, как показано ниже:

methods_and_procs/exceptions2.cr

def add_to_array(arr, number)

arr << number.to_i8

rescue

puts "integer bigger than 255"

end

Это упрощение также работает применительно к "ensure" (англ. — удостовериться), которое обычно используется для высвобождения ресурсов или очистки.

 

Использование рекурсивных методов

Метод может вызвать сам себя — например, здесь вычисляется факториал целого числа в методе "fact":

methods_and_procs/factorial.cr

def fact(n)

n == 0? 1: n * fact(n - 1)

end

fact(5) # => 120

Этот метод с радостью принимает любой аргумент, но посмотрите,
что случится, если скормить ему отрицательное целочисленное зна-
чение или строку:

fact(-2) # => Runtime error: Invalid memory access

(signal 11) at address 0x7ffbff7fdff8

fact("Crystal") # => Error: undefined method  '-' for String

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

methods_and_procs/factorial2.cr

def fact(n: Int): Int

if n < 0

raise ("n cannot be negative!")

end

n == 0? 1: n * fact(n - 1)

end

 fact(5) # => 120

begin

fact(-2) # => Runtime error: n cannot be negative! (Exception)

rescue ex

p ex.message

end

# => "n cannot be negative!"

 fact("Crystal") # => Error: no overload matches 'fact' with type String

 

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

И передача строкового аргумента блокируется на стадии компиляции с четким сообщением о несовпадении типов аргумента и параметра. Но
если вы не хотите использовать громоздкую конструкцию "begin-rescue", тогда просто напечатайте сообщение об ошибке и выйдите (exit) из программы:

methods_and_procs/factorial3.cr

def fact(n: Int): Int

 if n < 0

puts "n must be positive!"

exit

end

n == 0? 1: n * fact(n - 1)

end

fact(5) # => 120

fact(-2) # => "n must be positive!"

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

def some_method(n: Int)

return nil unless n > 1

# other code, here  n  is > 1

end

Вы можете вернуть нулевое (nil) или ложное (false) значение, или
любое другое значение, которое вы считаете нужным. Некоторые люди
в подобных случаях любят использовать unless, поскольку в нем содержится условие, которое должно быть выполнено, и потому оно кажется легче для понимания.

Помните, что ошибки дороги. Оставляйте шанс для потенциальных ошибок только тогда, когда несоблюдение важного условия требует особого внимания.

 

▪ Свертывание очереди рекурсивных вызовов ▪

 

Некоторые языки, произошедшие от Ruby, в частности Elixir, позво-
ляют рекурсии продлеваться все глубже и глубже, пока функция не потребует дополнительной информации для корректировки маршрута. Если возможно, эти ЯП выполняют так называемую оптимизацию остаточного вызова, проницательно изучая рекурсивные вызовы функции в ее последней строке и подчищая рутинные служебные
данные, которыми сопровождаются вызовы.

В прямом смысле Crystal не поддерживает хвостовую оптимизацию обратных вызовов (близкий термин — хвостовая рекурсия), хотя с
опорой на компилятор LLVM это иногда срабатывает. Пока под-держивается длительный период рекурсии, вы можете проверить,
сколько же шагов нужно сделать в конкретных обстоятельствах.

 

Ваш черёд № 4

Пузырьковая сортировка:

Реализация алгоритма "Bubblesort" для сортировки массива (в виде программного псевдокода) найдется в Википедии. В вашей программе организуйте копирование вводимых данных с помощью метода dup. Напишите две версии алгоритма "Bubblesort", для сортировки по возрастанию и убыванию, используя "yield" и блок кода для каждой версии.

Заключение

Мы надеемся, вы уже убедились, что Crystal весьма универсален и
гибок в работе с аргументами метода. И он не испытывает затруднений, принимая и возвращая большие объемы числовых значений. Пере-
грузка с ограничением типов делает ваш код более надежным и часто более эффективным, в то время как разумное использование "Proc"
может сделать его более адаптивным.

В следующей главе мы поговорим о классах и структурах. Поглядим,
что Кристалл предложит вашему вниманию там.

 

 


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

Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...



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

0.014 с.