Грамматика типов
В следующих случаях:
- при задании ограничений типов
- при задании аргументов типов
- при объявлении переменных
- при объявлении псевдонимов
- при объявлении определений типов (typedef)
- в качестве аргумента псевдовызова is_a?
- в качестве аргумента выражения as
- в качестве аргумента выражения sizeof
- в качестве аргумента выражения instance_sizeof
- при задании типа возвращаемого значения метода
для некоторых распространённых типов предусмотрен удобный синтаксис. Он особенно полезен при написании привязок C, но может использоваться в любом из перечисленных выше случаев.
Пути и обобщённые типы
Можно использовать обычные типы и обобщённые типы:
Int32
My::Nested::Type
Array(String)
Объединение
alias Int32OrString = Int32 | String
Вертикальная черта (|) в типах создаёт объединённый тип. Int32 | String читается как «Int32 или String». В обычном коде Int32 | String означает вызов метода | для Int32 с аргументом String.
Допускающий nil
alias Int32OrNil = Int32?
эквивалентно:
alias Int32OrNil = Int32 | ::Nil
В обычном коде Int32? сам является объединённым типом Int32 | ::Nil.
Указатель
alias Int32Ptr = Int32*
эквивалентно:
alias Int32Ptr = Pointer(Int32)
В обычном коде Int32* означает вызов метода * для Int32.
StaticArray
alias Int32_8 = Int32[8]
эквивалентно:
alias Int32_8 = StaticArray(Int32, 8)
В обычном коде Int32[8] означает вызов метода [] для Int32 с аргументом 8.
Кортеж
alias Int32StringTuple = {Int32, String}
эквивалентно:
alias Int32StringTuple = Tuple(Int32, String)
В обычном коде {Int32, String} — это экземпляр кортежа, содержащий Int32 и String в качестве элементов. Он отличается от указанного выше типа кортежа.
Именованный кортеж
alias Int32StringNamedTuple = {x: Int32, y: String}
эквивалентно:
alias Int32StringNamedTuple = NamedTuple(x: Int32, y: String)
В обычном коде {x: Int32, y: String} — это экземпляр именованного кортежа, содержащий Int32 и String для x и y. Он отличается от указанного выше типа именованного кортежа.
Proc
alias Int32ToString = Int32 -> String
эквивалентно:
alias Int32ToString = Proc(Int32, String)
Чтобы указать Proc без параметров:
alias ProcThatReturnsInt32 = -> Int32
Чтобы указать несколько параметров:
alias Int32AndCharToString = Int32, Char -> String
Для вложенных Proc (и вообще для любых типов) можно использовать круглые скобки:
alias ComplexProc = (Int32 -> Int32) -> String
В обычном коде Int32 -> String — синтаксическая ошибка.
self
self можно использовать в грамматике типов для обозначения типа self. См. раздел «Ограничения типов».
Класс
class используется для ссылки на тип класса, а не на тип экземпляра.
Например:
def foo(x : Int32)
"instance"
end
def foo(x : Int32.class)
"class"
end
foo 1 # "instance"
foo Int32 # "class"
class также полезен для создания массивов и коллекций типа класса:
class Parent
end
class Child1 < Parent
end
class Child2 < Parent
end
ary = [] of Parent.class
ary << Child1
ary << Child2
Подчёркивание
В ограничениях типов допускается символ подчёркивания. Он соответствует любому типу:
# Same as not specifying a restriction, not very useful
def foo(x : _)
end
# A bit more useful: any two-parameter Proc that returns an Int32:
def foo(x : _, _ -> Int32)
end
В обычном коде _ означает переменную подчёркивания.
typeof
В грамматике типов допускается typeof. Оно возвращает объединённый тип типов переданных выражений:
typeof(1 + 2) # => Int32
typeof(1, "a") # => (Int32 | String)
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/type_grammar.html