struct Tuple(*T)
- Tuple(*T)
- Value
- Object
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
- Comparable(Tuple(*T))
- Indexable(Union(*T))
Defined in:
lib/msgpack/src/message_pack/to_msgpack.crprimitives.cr