Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
Топ:
История развития методов оптимизации: теорема Куна-Таккера, метод Лагранжа, роль выпуклости в оптимизации...
Основы обеспечения единства измерений: Обеспечение единства измерений - деятельность метрологических служб, направленная на достижение...
Когда производится ограждение поезда, остановившегося на перегоне: Во всех случаях немедленно должно быть ограждено место препятствия для движения поездов на смежном пути двухпутного...
Интересное:
Берегоукрепление оползневых склонов: На прибрежных склонах основной причиной развития оползневых процессов является подмыв водами рек естественных склонов...
Как мы говорим и как мы слушаем: общение можно сравнить с огромным зонтиком, под которым скрыто все...
Средства для ингаляционного наркоза: Наркоз наступает в результате вдыхания (ингаляции) средств, которое осуществляют или с помощью маски...
Дисциплины:
2022-09-29 | 26 |
5.00
из
|
Заказать работу |
|
|
Помните, как мы получали пользовательский ввод данных, заполняли ими массив и предотвращали вероятную исключительную ситуацию с помощью "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"
может сделать его более адаптивным.
В следующей главе мы поговорим о классах и структурах. Поглядим,
что Кристалл предложит вашему вниманию там.
|
|
Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...
Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...
Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьшения длины пробега и улучшения маневрирования ВС при...
Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!