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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 4 5 6 7 8 9 10 11 12 ... 75
Перейти на страницу:
class="empty-line"/>

Диапазоны также можно применять к разным типам; подумайте, например, о временных интервалах.

С диапазонами можно выполнять множество операций. В частности, Range реализует как Enumerable, так и Iterable, что позволяет ему действовать как сбор данных. Вот несколько служебных методов:

Таблица 2.6 – Общие операции со значениями диапазона

Вы уже можете выражать некоторые данные, используя литеральные значения и переменные в своем коде. Этого достаточно для некоторых базовых вычислений; попробуйте использовать его для некоторых преобразований строк или математических формул. Некоторые виды значений можно сначала объявить, чтобы использовать позже; перечисления — самые простые из них.

Перечисления и символы (Enums and symbols)

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

Например, предположим, что вы взаимодействуете с каким-либо пользователем в многопользовательской системе. Этот конкретный пользователь может быть гостем, обычным пользователем, прошедшим проверку подлинности, или администратором. Каждый из них имеет разные возможности, и их следует различать. Это можно сделать с помощью числового кода для представления каждого типа пользователей, например 0, 1 и 2. Или это можно сделать с использованием типа String, имеющего типы пользователей «гость», «обычный» и «администратор».

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

enum UserKind

   Guest

   Regular

   Admin

end

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

user_kind = UserKind::Regular

puts "This user is of kind #{user_kind}"

Тип переменной user_kind — UserKind, точно так же, как тип 20 — Int32. В следующей главе вы узнаете, как создавать более сложные пользовательские типы. Для каждой потребности могут быть созданы разные перечисления; они не будут смешиваться друг с другом.

Значение перечисления можно проверить с помощью метода, сгенерированного из каждой альтернативы. Вы можете использовать user_kind.guest? чтобы проверить, содержит ли этот user_kind тип Guest или нет. Аналогично, regular? и admin? методы можно использовать для проверки других типов.

Объявление и использование перечислений — предпочтительный способ обработки набора известных альтернатив. Например, они позаботятся о том, чтобы вы никогда не ошиблись в написании типа пользователя. В любом случае перечисления — не единственный вариант. Crystal также имеет тип Symbol.

Символ подобен программному анонимному перечислению, которое не нужно объявлять. Вы можете просто ссылаться на символы, добавляя двоеточие к имени символа. Они могут выглядеть и ощущаться очень похожими на строки, но их имена не предназначены для проверки и манипулирования ими, как со строками; вместо этого они оптимизированы для сравнения и не могут создаваться динамически:

user_kind = :regular

puts "This user is of kind #{user_kind}"

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

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

Управление потоком выполнения с помощью условных выражений

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

if и unless

Оператор if можно использовать для проверки условия; если оно истинно (то есть не равно nil и не false), то оператор внутри него выполняется. Вы можете использовать else, чтобы добавить действие, если условие неверно. Посмотрите это, например:

secret_number = rand(1..5) # Случайное целое число от 1 до 5

print "Пожалуйста, введите свое предположение:"

guess = read_line.to_i

if guess == secret_number

   puts "Вы правильно догадались!"

else

   puts "Извините, номер был #{secret_number}."

end

Условное выражение не обязательно должно быть выражением, результатом которого является логическое значение (true или false). Любое значение, кроме ложных, нулевых и нулевых указателей (подробнее об указателях см. в Главе 7, «C Функциональная совместимость»), будет считаться правдивым. Обратите внимание, что нулевые и пустые строки также являются правдивыми.

Противоположностью if является unless. Его можно использовать, когда вы хотите отреагировать, когда условие является false или nil. Посмотрите это, например:

unless guess.in? 1..5

   puts "Пожалуйста, введите число от 1 до 5."

end

Оператор if также может содержать блок else, но в этом случае всегда лучше изменить порядок на обратный и использовать последовательность if-else.

И if, и unless можно записать в одну строку, вставив ее после действия. В некоторых случаях это более читабельно. Предыдущий пример аналогичен этому:

puts "Пожалуйста, введите число от 1 до 5." unless guess.in? 1..5

Вы можете объединить несколько операторов if, используя один или несколько блоков elsif. Это уникально для if и не может использоваться с unless. Посмотрите это, например:

if !guess.in? 1..5

   puts "Пожалуйста, введите число от 1 до 5."

elsif guess == secret_number

   puts "Вы правильно угадали!"

else

   puts "Извините, номер был #{secret_number}."

end

Как вы часто увидите в Crystal, эти операторы также можно использовать как выражения; они выдадут последний оператор выбранной ветки. Вы даже можете использовать блок if в середине присваивания

1 ... 4 5 6 7 8 9 10 11 12 ... 75
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?