Desestruturação
Extrair vários valores de uma vez, por posição ou por nome.
Por posição#
a, b := [1, 2]
x, y, z := [10, 20, 30]
out a, b, x + y + zO lado direito é percorrido e cada elemento vai para o nome correspondente.
A troca sem temporária#
p := "primeiro"
q := "segundo"
p, q := q, p
out p, qO lado direito é avaliado inteiro antes de qualquer atribuição acontecer. Por isso não há variável temporária nem risco de sobrescrever p antes de ler.
Quantidade errada falha#
m, n := [1, 2, 3]
# Cannot unpack 3 value(s) into 2 name(s)Isso é deliberado. Um [1, 2, 3] chegando onde se esperavam dois valores quase sempre significa que a suposição sobre os dados estava errada — e falhar alto é melhor que descartar o 3 em silêncio.
Com ...resto#
primeiro, ...outros := [1, 2, 3, 4, 5]
out primeiro, outros # 1 [2, 3, 4, 5]
inicio, ...meio, fim := [1, 2, 3, 4, 5]
out inicio, meio, fim # 1 [2, 3, 4] 5
so_um, ...nada := [9]
out nada # [] — resto vazio é válidoSó é permitido um ...resto por desestruturação — com dois, não haveria como saber onde um termina e o outro começa.
Por nome#
Com chaves, a desestruturação passa a ser por nome, e a ordem não importa:
record Usuario:
nome: String
idade: Integer
cidade: String
u := Usuario("Ana", 30, "Floripa")
{nome, cidade} := u
out $"{nome} mora em {cidade}"
config := {"host": "localhost", "porta": 8080}
{host, porta} := config
out $"{host}:{porta}"| Forma | Casa por | Fonte |
|---|---|---|
a, b := … | posição | lista, record |
{a, b} := … | nome | vault, record, instância |
Chave ausente falha#
Vault has no key 'inexistente' to destructure. Keys: host, porta, debugA mensagem lista as chaves que existem — quase sempre o erro é um nome digitado errado, e ver a lista resolve na hora.
Resto nomeado#
{nome, ...resto} := u
out resto # {idade: 30, cidade: Floripa}Útil para "pegue esses dois campos e passe o resto adiante" — um padrão comum ao tratar requisições HTTP.
Desempacotar no início da ação#
action apresentar(pessoa):
{nome, idade} := pessoa
yield $"{nome}, {idade} anos"Duas vantagens sobre usar pessoa.nome no corpo inteiro: a primeira linha documenta o que a ação consome, e o resto do corpo fica mais curto.
Retornar vários valores#
DataForge não tem tuplas separadas de listas. Devolver vários valores é devolver uma lista, e quem chama desestrutura:
action divide_com_resto(a, b):
yield [a ~/ b, a % b]
quociente, resto := divide_com_resto(17, 5)
out $"17 / 5 = {quociente} resto {resto}"Isso lê melhor que resultado[0] e resultado[1] espalhados pelo código.
Comparando#
| DataForge | JavaScript | Python |
|---|---|---|
a, ...r := lista | const [a, ...r] = lista | a, *r = lista |
{a, b} := obj | const {a, b} = obj | — |