Una tupla es el agrupamiento de dos o más expresiones que se tratan como una sola expresión.
Un literal de tupla tiene múltiples expresiones entre () con los elementos separados por comas:
(1, 2, 3)
El orden de los elementos en una tupla es importante. La siguiente tupla es diferente del ejemplo de tupla anterior:
(3, 2, 1)
La misma expresión puede estar en múltiples posiciones en una tupla:
("Help me Rhonda", "Help", "Help me Rhonda")
Las expresiones de tupla pueden ser de cualquier tipo y pueden contener tipos mezclados, (a diferencias de las matrices que solo pueden tener elementos de un tipo):
(1, 2.0, "three")
Las tuplas pueden contener incluso otras tuplas:
(1, (10, 20.0, "thirty"), "three")
Si estás familiarizado con estos términos, una tupla es como:
- Una estructura de datos sin nombre con elementos sin nombre ordenados
- Una matriz de tamaño fijo donde cada elemento puede ser de un tipo diferente
Las tuplas son especialmente útiles para:
- Devolver varios valores desde una función.
- Un agrupamiento simple implementado que es más conciso que el trabajo de realizar una estructura de datos reutilizable totalmente descrita (como una estructura o clase).
Cómo especificar una variable con un tipo tupla
Para especificar el tipo de variable como una tupla, se usa el prefijo «tuple» antes de los tipos separados por comas encerrados entre «()»:
MyTupleInts : tuple(int, int, int) = (1, 2, 3)
MyTupleMixed : tuple(int, float, string) = (1, 2.0, "three")
MyTupleNested : tuple(int, tuple(int, float, string), string) = (1, (10, 20.0, "thirty"), "three")
Los tipos de tupla también pueden inferirse:
MyTupleInts := (1, 2, 3)
MyTupleMixed := (1, 2.0, "three")
MyTupleNested := (1, (10, 20.0, "thirty"), "three")
Se pueden usar especificadores del tipo tupla en miembros de datos y firmas de tipo de función para parámetros o un tipo devolver:
ExampleFunction(Param1 : tuple(string, int), Param2 : tuple(int, string)) : tuple(string, int) =
# Uso de un parámetro como resultado
Param1
Acceso a los elementos de una tupla
Se puede acceder a los elementos de una tupla con un operador de [índice] con base cero que no fracase (verse-glossary#index) que tome un entero. El operador de índice no puede fracasar (a diferencia de un operador de índice de matriz [index] que puede fracasar) porque el compilador siempre conoce el número de elementos en cualquier tupla por lo que cualquier índice fuera de límite producirá un error de tiempo de compilación:
MyTuple := (1, 2.0, "three")
MyNestedTuple := (1, (10, 20.0, "thirty"), "three")
var MyInt: int = MyTuple(0)
var MyFloat: float = MyTuple(1)
var MyString: string = MyTuple(2)
Print("Mis variables: {MyInt}, {MyFloat}, {MyString}")
Print("Mi elemento de tupla anidada: {MyNestedTuple(1)(2)}")
Conversión de matriz a tupla
Es posible pasar tuplas cuando se espere una matriz, siempre que los elementos de la tupla sean todos del mismo tipo que la matriz. No se pueden pasar matrices cuando se espera una tupla.
Expansión de tupla
Una tupla que se pasa como un solo elemento a una función será como si se llama a dicha función con cada uno de los elementos de la tupla separadamente. Esto se denomina expansión de tupla o splatting.
F(Arg1 : int, Arg2 : string) : void =
DoStuff(Arg1, Arg2)
G() : void =
MyTuple := (1, "two")
F(MyTuple(0), MyTuple(1)) # Acceso a elementos
F(MyTuple) # Expansión de tupla
La expresión sync concurrencia estructurada tiene un resultado de tupla que permite que varios argumentos que se evalúan en el tiempo se evalúen simultáneamente. Para obtener más información, consulta Concurrencia.
Tipos persistentes
Una tupla es persistente si cada tipo de elemento es persistente. Cuando una tupla es persistente, quiere decir que la puedes usar en tus variables weak_map del módulo y hacer que sus valores persistan a lo largo de las sesiones de juego. Para más información sobre la persistencia en Verse, consulta Cómo usar datos persistentes en Verse.