KnigkinDom.org» » »📕 Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих

Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих

Книгу Crystal Programming. Введение на основе проекта в создание эффективных, безопасных и читаемых веб-приложений и приложений CLI - Джордж Дитрих читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

1 ... 18 19 20 21 22 23 24 25 26 ... 75
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
class="code">Array(String). Универсальный класс Hash аналогичен, но у него есть два параметра типа — типы ключей и типы значений.

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

class Holder(T)

    def initialize(@value : T)

    end

    def get

        @value

    end

    def set(new_value : T)

        @value = new_value

    end

end

Общие параметры, по соглашению, представляют собой одиночные заглавные буквы — в данном случае T. В этом примере Holder является универсальным классом, а Holder(Int32) будет универсальным экземпляром этого класса: обычным классом, который может создавать объекты. Переменная экземпляра @value имеет тип T, независимо от того, какое T будет позже. Вот как можно использовать этот класс:

num = Holder(Int32).new(10)

num.set 40

p num.get # Prints 40.

В этом примере мы создаем новый экземпляр класса Holder(Int32). Это как если бы у вас был абстрактный класс Holder и наследуемый от него класс Holder_Int32, созданный по требованию для T=Int32. Объект можно использовать как любой другой. Методы вызываются и взаимодействуют с переменной экземпляра @value.

Обратите внимание, что в этих случаях тип T не обязательно указывать явно. Поскольку метод инициализации принимает аргумент типа T, общий параметр можно вывести из использования. Давайте создадим Holder(String):

str = Holder.new("Hello")

p str.get # Prints "Hello".

Здесь T считается строкой, поскольку Holder.new вызывается с аргументом строкового типа.

Классы-контейнеры из стандартной библиотеки являются универсальными классами, как и определенный нами класс Holder. Некоторые примеры: Array(T), Set(T) и Hash(K, V). Вы можете поиграть с созданием собственных классов контейнеров, используя дженерики.

Далее давайте узнаем, как вызывать и обрабатывать исключения.

Исключения

Существует множество способов, по которым код может сбоить. Некоторые сбои обнаруживаются во время анализа, например, невыполненный метод или нулевое значение в переменной, которое не должно содержать nil. Некоторые другие сбои происходят во время выполнения программы и описываются специальными объектами: исключениями. Исключение представляет собой сбой на "счастливом пути" и содержит точное местоположение, в котором была обнаружена ошибка, а также подробные сведения для ее понимания.

Исключение может быть вызвано в любой момент с помощью метода верхнего уровня raise. Этот метод ничего не вернет; вместо этого он начнет выполнять обратные вызовы всех методов, как если бы все они имели неявный возврат. Если ничто не фиксирует исключение выше в цепочке методов, программа завершит работу, и пользователю будут представлены подробные сведения об исключении. Приятным аспектом возникновения исключения является то, что оно не должно останавливать выполнение программы; вместо этого его можно перехватить и обработать, возобновив нормальное выполнение.

Давайте рассмотрим пример:

def half(num : Int)

    if num.odd?

      raise "The number #{num} isn't even"

    end

    num // 2

end

p half(4) # => 2

p half(5) # Unhandled exception: The number 5 isn't even (Exception)

p half(6) # This won't execute as we have aborted the program.

В предыдущем фрагменте мы определили метод half, который возвращает половину заданного целого числа, но только для четных чисел. Если задано нечетное число, это вызовет исключение. В этой программе нет ничего, что могло бы перехватить и обработать это исключение, поэтому программа завершит работу с сообщением о необработанном исключении.

Обратите внимание, что raise "описание ошибки" – это то же самое, что raise Exception. new("описание ошибки"), поэтому будет создан объект exception. Exception - это класс, единственная особенность которого заключается в том, что метод raise принимает только его объекты.

Чтобы показать разницу между ошибками во время компиляции и во время выполнения, попробуйте добавить p half("привет") к предыдущему примеру. Теперь это недопустимая программа (из-за несоответствия типов), и она даже не собирается, поэтому не может быть запущена. Ошибки во время выполнения обнаруживаются и сообщаются только во время выполнения программы.

Исключения могут быть зафиксированы и обработаны с помощью ключевого слова rescue. Оно чаще используется в выражениях begin и end, но может использоваться непосредственно в телах методов или блоков. Вот пример:

begin

    p half(3)

rescue

    puts "can't compute half of 3!"

end

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

begin

    p half(3)

rescue error

    puts "can't compute half of 3 because of #{error}"

end

Здесь мы зафиксировали объект exception и можем его проверить. Мы могли бы даже вызвать его снова, используя raise error. Та же концепция может быть применена к телам методов:

def half?(num)

    half(num)

rescue

    nil

end

p half? 2 # => 1

p half? 3 # => nil

p half? 4 # => 2

В этом примере у нас есть версия метода half, которая называется half?. Этот метод возвращает объединение Int32 | Nil, в зависимости от введенного номера.

Наконец, ключевое слово rescue также можно использовать встроенно, чтобы защитить одну строку кода от любого исключения и заменить ее значение. Метод half? можно реализовать следующим образом:

def half?(num)

    half(num) rescue nil

end

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

Стандартная библиотека содержит множество типов предопределенных исключений, таких как DivisionByZeroError, IndexError и JSON::Error. Каждый из них представляет различные типы ошибок. Это простые классы, которые наследуются от класса Exception.

Пользовательские исключения

Поскольку исключения - это обычные объекты, а Exception - это класс, вы можете определять новые типы исключений, наследуя от них. Давайте посмотрим на это на практике:

class OddNumberError

1 ... 18 19 20 21 22 23 24 25 26 ... 75
Перейти на страницу:
Отзывы - 0

Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.


Партнер

Новые отзывы

  1. Kelly Kelly11 июль 05:50 Хорошо написанная книга, каждая глава читалась взахлёб. Всё описано так ярко: образы, чувства, страх, неизбежность, словно я сама... Не говори никому. Реальная история сестер, выросших с матерью-убийцей - Грегг Олсен
  2. Аноним Аноним09 июль 05:35 Главная героиня- Странная баба, со всеми переспала. Сосед. Татьяна Шумакова.... Сосед - Татьяна Александровна Шумкова
  3. ANDREY ANDREY07 июль 21:04 Прекрасное произведение с первой книги!... Роботам вход воспрещен. Том 7 - Дмитрий Дорничев
Все комметарии
Новое в блоге