Pular para o conteúdo

Spread e rest

O operador ... expandindo coleções e coletando o que sobra.

Dois trabalhos opostos#

... faz coisas diferentes conforme o lado em que aparece:

PosiçãoSignificaExemplo
esquerda do :=coletaa, ...resto := lista
dentro de […]expande[...a, ...b]
dentro de {…}expande{...padrao, ...usuario}
numa chamadaexpande argumentosf(...args)

Expandir listas#

dataforge
a := [1, 2]
b := [3, 4]

out [...a, ...b, 5]           # [1, 2, 3, 4, 5]
out [0, ...a]                 # [0, 1, 2]
out [...antes, novo, ...depois]   # inserir no meio

Expandir vaults#

Esta é a aplicação mais comum, e resolve num gesto o que normalmente seriam cinco linhas:

dataforge
padrao := {"tema": "claro", "fonte": 14}
usuario := {"tema": "escuro"}

final := {...padrao, ...usuario}
out final                     # {tema: escuro, fonte: 14}

O último vence. As preferências do usuário sobrescrevem o padrão; o que ele não definiu vem do padrão.

Expandir argumentos#

dataforge
action somar(a, b, c):
    yield a + b + c

args := [1, 2, 3]
out somar(...args)            # 6

Cópia rasa#

dataforge
original := [1, 2, 3]
copia := [...original]
copia.append(4)

out original, copia           # [1, 2, 3] [1, 2, 3, 4]

Cria uma lista nova. É "rasa" porque objetos dentro da lista continuam compartilhados — para uma cópia profunda existe deep_copy.

Coletar com ...resto#

dataforge
primeiro, ...outros := [1, 2, 3, 4]
{nome, ...campos} := usuario

Detalhes em Desestruturação.

Em pattern matching#

dataforge
match lista:
    point [primeiro, ...resto]:
        yield $"comeca com {primeiro}, mais {len(resto)}"
    point ["dizer", ...palavras]:
        yield $"dizendo: {palavras.join(" ")}"

O que pode ser expandido#

  • Cluster — os elementos
  • String — os caracteres
  • Vault — as chaves (em lista) ou os pares (em vault)
  • Stream — materializa e expande
  • Um record ou instância, dentro de {…} — os campos

Espalhar um número ou void dispara erro com a mensagem explicando o que se espera.

Comparando#

DataForgeJavaScriptPython
[...a, ...b][...a, ...b][*a, *b]
{...a, ...b}{...a, ...b}{**a, **b}
f(...args)f(...args)f(*args)