a = 10
p typeof(a) # => Int32
# Измените 'a', чтобы оно стало строкой String
a = "привет"
p typeof(a) # => String
# Возможно, 'a' изменится на Float64
if rand(1..2) == 1
a = 1.5
p typeof(a) # => Float64
end
# Теперь переменная 'a' может быть либо String либо Float64
p typeof(a) # => String | Float64
# Но мы можем узнать во время выполнения, какой это тип.
if a.is_a? String
puts "Это String"
p typeof(a) # => String
else
puts "Это Float64"
p typeof(a) # => Float64
end
# Тип 'a' был отфильтрован внутри условного выражения, но не изменился.
p typeof(a) # => String | Float64
# Вы также можете использовать .class для получения типа среды выполнения
puts "It's a #{a.class}"
В Crystal каждое значение является объектом, даже примитивные типы, такие как целые числа. Объекты имеют тип, и этот тип может реагировать на вызовы методов. Все операции, которые вы выполняете над объектом, проходят через вызов какого-либо метода. Даже nil
является объектом типа Nil
и может реагировать на методы. Например, nil.inspect
возвращает "nil
".
Все переменные имеют тип или, возможно, объединение нескольких типов. Когда это объединение, оно сохраняет объект одного из типов во время выполнения. Фактический тип можно определить с помощью оператора is_a?
.
Методы, доступные данному типу, всегда известны компилятору. Таким образом, попытка вызвать несуществующий метод приведет к ошибке времени компиляции, а не к исключению времени выполнения.
К счастью, у Crystal есть инструмент, который помогает нам визуализировать типы по мере их вывода. Следующий раздел проведет вас через это.
Экспериментируем с командой Crystal Play
Команда crystal play
запускает Crystal Playground для воспроизведения языка с помощью вашего браузера. Он покажет результат каждой строки вместе с выведенным типом:
1. Откройте терминал и введите "crystal play”; он покажет следующее сообщение:
Listening on http://127.0.0.1:8080
2. Оставьте терминал открытым, а затем запустите этот URL-адрес в своем любимом веб-браузере. Это даст вам удобный интерфейс для начала программирования в Crystaclass="underline"
Рисунок 2.1 - The Crystal playground
1. С левой стороны у вас есть текстовый редактор с некоторым кодом Crystal. Вы можете попробовать изменить код на какой-нибудь код из этой книги, чтобы получить интерактивный способ обучения.
2. С правой стороны есть поле с некоторыми аннотациями к вашему коду. Например, он покажет вам результат каждой строки рядом с типом значения, видимым компилятором.
Если вы сомневаетесь в каких-то примерах или нестандартных решениях, попробуйте их с помощью Crystal playground.
Переходя к более практичному представлению о том, как используются типы, нам нужно узнать о хранении данных в коллекциях и манипулировании ими. Они всегда печатаются на машинке для обеспечения безопасности.
Организация вашего кода по методам
При написании приложений код необходимо структурировать таким образом, чтобы его можно было повторно использовать, документировать и тестировать. Основой этой структуры является создание методов. В следующей главе мы перейдем к объектно-ориентированному программированию с классами и модулями. Метод имеет имя, может получать параметры и всегда возвращает значение (nil
также является значением). Посмотрите это, например:
def leap_year?(year) divides_by_4 = (year % 4 == 0)
divides_by_100 = (year % 100 == 0)
divides_by_400 = (year % 400 == 0)
divides_by_4 && !(divides_by_100 && !divides_by_400)
end
puts leap_year? 1900 # => false
puts leap_year? 2000 # => true
puts leap_year? 2020 # => true
Определения методов начинаются с ключевого слова def
, за которым следует имя метода. В данном случае имя метода — jump_year?
, включая символ вопроса. Затем, если у метода есть параметры, они будут заключены в круглые скобки. Метод всегда возвращает результат своей последней строки, в данном примере — условный результат. Типы не нужно указывать явно, они будут определяться в зависимости от использования.