Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
Топ:
Характеристика АТП и сварочно-жестяницкого участка: Транспорт в настоящее время является одной из важнейших отраслей народного...
Установка замедленного коксования: Чем выше температура и ниже давление, тем место разрыва углеродной цепи всё больше смещается к её концу и значительно возрастает...
Основы обеспечения единства измерений: Обеспечение единства измерений - деятельность метрологических служб, направленная на достижение...
Интересное:
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Аура как энергетическое поле: многослойную ауру человека можно представить себе подобным...
Берегоукрепление оползневых склонов: На прибрежных склонах основной причиной развития оползневых процессов является подмыв водами рек естественных склонов...
Дисциплины:
2022-09-29 | 23 |
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"
может сделать его более адаптивным.
В следующей главе мы поговорим о классах и структурах. Поглядим,
что Кристалл предложит вашему вниманию там.
|
|
Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьшения длины пробега и улучшения маневрирования ВС при...
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!