Uma tupla é um agrupamento de duas ou mais expressões que é tratado como uma única expressão.
Um literal de tupla tem várias expressões entre (), com os elementos separados por vírgulas:
(1, 2, 3)
A ordem dos elementos em uma tupla é importante. A tupla a seguir é diferente do exemplo de tupla anterior:
(3, 2, 1)
~~~
A mesma expressão também pode estar em várias posições em uma tupla:
~~~(verse)
("Help me Rhonda", "Help", "Help me Rhonda")
Expressões de tupla podem ser de qualquer tipo e podem conter tipos mistos (diferentemente de matrizes que só podem ter elementos de um tipo):
(1, 2.0, "three")
Tuplas podem até mesmo conter outras tuplas:
(1, (10, 20.0, "thirty"), "three")
Se você está familiarizado com estes termos, uma tupla é como:
- Uma estrutura de dados sem nome com elementos ordenados sem nome
- Uma matriz de tamanho fixo onde cada elemento pode ser de um tipo diferente
Tuplas são especialmente úteis para:
- Retornando vários valores de uma função.
- Um agrupamento simples no local que é mais conciso do que a sobrecarga de criar uma estrutura de dados totalmente descrita e reutilizável (como uma estrutura ou uma classe).
Como especificar uma variável com um tipo de tupla
Para especificar o tipo de variável como uma tupla, o prefixo tuple é usado antes dos tipos separados por vírgula 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")
~~~
Os tipos de tupla também podem ser [inferidos](verse-glossary#infer):
~~~(verse)
MyTupleInts := (1, 2, 3)
MyTupleMixed := (1, 2.0, "three")
MyTupleNested := (1, (10, 20.0, "thirty"), "three")
Especificadores de tipos de tupla podem ser usados em membros de dados e assinaturas de tipo de função para parâmetros ou um tipo de retorno:
ExampleFunction(Param1 : tuple(string, int), Param2 : tuple(int, string)) : tuple(string, int) =
# Como usar um parâmetro como resultado
Param1
~~~
## Acesso aos elementos da tupla
Os elementos de uma tupla podem ser acessados com um [operador](verse-glossary#operator) de [índice](verse-glossary#index) baseado em zero e sem falhas que recebe um número inteiro. O operador de índice não pode falhar (ao contrário de um operador de índice de matriz `[index]` que pode falhar), porque o compilador sempre sabe o número de elementos de qualquer tupla e, portanto, qualquer índice fora dos limites será um erro de [tempo de compilação](verse-glossary#compile-time):
~~~(verse)
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("Minhas variáveis: {MyInt}, {MyFloat}, {MyString}")
Print("Meu elemento de tupla aninhado: {MyNestedTuple(1)(2)}")
Coerção de matrizes de tuplas
As tuplas podem ser passadas onde quer que uma matriz seja esperada, desde que o tipo dos elementos da tupla seja do mesmo tipo que o da matriz. As matrizes não podem ser passadas onde uma tupla é esperada.
Expansão da tupla
Uma tupla transmitida como um único elemento a uma função será como se essa função fosse chamada com cada um dos elementos dessa tupla separadamente. Isso é chamado de expansão de tupla, ou splatting.
F(Arg1 : int, Arg2 : string) : void =
DoStuff(Arg1, Arg2)
G() : void =
MyTuple := (1, "two")
F(MyTuple(0), MyTuple(1)) # Acessando elementos
F(MyTuple) # Expansão da tupla
A expressão sync de coocorrência estruturada tem um resultado de tupla que permite vários argumentos que avaliam ao longo do tempo para serem avaliados simultaneamente. Obtenha mais informações em Coocorrência.
Tipo persistente
Uma tupla é persistente se cada tipo de elemento é persistente. Quando uma tupla é persistente, você pode usá-la nas variáveis weak_map com escopo de módulo e fazer com que seus valores persistam entre as sessões de jogo. Consulte mais detalhes sobre a persistência em Verse em: Como usar dados persistentes no Verse.