Type grammar

    a convenient syntax is provided for some common types. These are especially useful when writing , but can be used in any of the above locations.

    Regular types and generics can be used:

    Union

    The pipe (|) in types creates a union type. Int32 | String is read “Int32 or String”. In regular code, Int32 | String means invoking the method | on Int32 with String as an argument.

    Nilable

    1. alias Int32OrNil = Int32?

    is the same as:

    1. alias Int32OrNil = Int32 | ::Nil

    In regular code, Int32? is an Int32 | ::Nil union type itself.

    Pointer

    1. alias Int32Ptr = Int32*

    is the same as:

    1. alias Int32Ptr = Pointer(Int32)

    In regular code, Int32* means invoking the * method on Int32.

    1. alias Int32_8 = Int32[8]

    In regular code, Int32[8] means invoking the [] method on Int32 with 8 as an argument.

    Tuple

    1. alias Int32StringTuple = {Int32, String}

    is the same as:

    1. alias Int32StringTuple = Tuple(Int32, String)

    In regular code, {Int32, String} is a tuple instance containing Int32 and as its elements. This is different than the above tuple type.

    NamedTuple

    1. alias Int32StringNamedTuple = {x: Int32, y: String}

    is the same as:

    1. alias Int32StringNamedTuple = NamedTuple(x: Int32, y: String)

    In regular code, {x: Int32, y: String} is a named tuple instance containing Int32 and String for x and y. This is different than the above named tuple type.

    Proc

    1. alias Int32ToString = Int32 -> String

    is the same as:

    1. alias Int32ToString = Proc(Int32, String)

    To specify a Proc without parameters:

    1. alias Int32AndCharToString = Int32, Char -> String

    For nested procs (and any type, in general), you can use parentheses:

    1. alias ComplexProc = (Int32 -> Int32) -> String

    In regular code Int32 -> String is a syntax error.

    self can be used in the type grammar to denote a self type. Refer to the type restrictions section.

    class

    class is used to refer to a class type, instead of an instance type.

    For example:

    1. def foo(x : Int32)
    2. "instance"
    3. end
    4. def foo(x : Int32.class)
    5. "class"
    6. end
    7. foo 1 # "instance"

    class is also useful for creating arrays and collections of class type:

    1. class Parent
    2. end
    3. class Child1 < Parent
    4. end
    5. class Child2 < Parent
    6. end
    7. ary = [] of Parent.class
    8. ary << Child1
    9. ary << Child2

    Underscore

    An underscore is allowed in type restrictions. It matches anything:

    1. # Same as not specifying a restriction, not very useful
    2. def foo(x : _)
    3. end
    4. # A bit more useful: any two-parameter Proc that returns an Int32:
    5. def foo(x : _, _ -> Int32)
    6. end

    typeof

    typeof is allowed in the type grammar. It returns a union type of the type of the passed expressions:

    1. typeof(1, "a") # => (Int32 | String)