struct Tuple(*T)

Overview

A tuple is a fixed-size, immutable, stack-allocated sequence of values of possibly different types.

You can think of a Tuple as an immutable Array whose types for each position are known at compile time.

A tuple can be created with the usual new method or with a tuple literal:

tuple = {1, "hello", 'x'} # Tuple(Int32, String, Char)
tuple[0]                  # => 1
tuple[1]                  # => "hello"
tuple[2]                  # => 'x'

See Tuple literals in the language reference.

The compiler knows what types are in each position, so when indexing a tuple with an integer literal the compiler will return the value in that index and with the expected type, like in the above snippet. Indexing with an integer literal outside the bounds of the tuple will give a compile-time error.

Indexing with an integer value that is only known at runtime will return a value whose type is the union of all the types in the tuple, and might raise IndexError.

Indexing with #[]? does not make the return value nilable if the index is known to be within bounds:

tuple = {1, "hello", 'x'}
tuple[0]?         # => 1
typeof(tuple[0]?) # => Int32

Indexing with a range literal known at compile-time is also allowed, and the returned value will have the correct sub-tuple type:

tuple = {1, "hello", 'x'} # Tuple(Int32, String, Char)
sub = tuple[0..1]         # => {1, "hello"}
typeof(sub)               # => Tuple(Int32, String)

Tuple's own instance classes may also be indexed in a similar manner, returning their element types instead:

tuple = Tuple(Int32, String, Char)
tuple[0]   # => Int32
tuple[3]?  # => nil
tuple[1..] # => Tuple(String, Char)

Tuples are the preferred way to return fixed-size multiple return values because no memory is needed to be allocated for them:

def one_and_hello
  {1, "hello"}
end

one, hello = one_and_hello
one   # => 1
hello # => "hello"

Good examples of the above are Number#divmod and Enumerable#minmax.

Tuples can be splat with the * operator and passed to methods:

def multiply(string, value)
  string * value
end

tuple = {"hey", 2}
value = multiply(*tuple) # same as multiply tuple[0], tuple[1]
value                    # => "heyhey"

Finally, when using a splat argument in a method definition its type will be a tuple of the call arguments:

def splat_test(*args)
  args
end

tuple = splat_test 1, "hello", 'x'
tuple.class # => Tuple(Int32, String, Char)
tuple       # => {1, "hello", 'x'}

Included Modules

Defined in:

cannon/core_ext.cr

Class Method Summary

Instance Method Summary

Class methods inherited from class Object

to_cannon_io(io, value) to_cannon_io

Class Method Detail

def self.from_cannon_io(io) #

[View source]

Instance Method Detail

def to_cannon_io(io) #

[View source]