Выбрать главу

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?, включая символ вопроса. Затем, если у метода есть параметры, они будут заключены в круглые скобки. Метод всегда возвращает результат своей последней строки, в данном примере — условный результат. Типы не нужно указывать явно, они будут определяться в зависимости от использования.