09 — Coleções
Meta do capítulo: armazenar e processar dados com listas, dicts, sets e tuplas. Referência:
../language-reference/expressions.md§14, §16. Exemplo:../../examples/tour.aura.
Literais
let list = [1, 2, 3]
let set = {1, 2, 3}
let dict = {name: "Alice", age: 30}
let pair = (1, "hello")
let single = (42,)
let empty = ()
- Listas usam
[ ... ]. - Sets usam
{ ... }sem:. - Dicts usam
{ key: value }. Acesso por índiced["k"]ou por membrod.kfuncionam. - Tuplas precisam da vírgula:
(42,)é uma tupla de um elemento;(42)é apenas42.
Uma vírgula à direita é permitida em todos os lugares. Dicts preservam a ordem de inserção (CPython 3.7+).
Indexação e slices
let numbers = [10, 20, 30, 40]
print(numbers[0]) // 10
print(numbers[-1]) // 40 — negative index
print(numbers[1:3]) // [20, 30]
print(numbers[::2]) // [10, 30]
Um range usado como índice é um slice:
print(numbers[0..<2]) // [10, 20] — exclusive upper bound
print(numbers[0..2]) // [10, 20, 30] — inclusive
print(numbers[1..]) // [20, 30, 40] — open end
Tamanho, pertinência e mutação
let numbers = [1, 2, 3]
numbers.add(4) // append
print(numbers.length()) // 4
print(numbers.size()) // 4
print(numbers.contains(2)) // true
print(numbers.is_empty()) // false
print(2 in numbers) // true
.length() / .size() → len(x); .contains(x) → x in x; .add(x) → append. Um método declarado pelo usuário com um desses nomes vence sobre a conveniência.
Chamadas de membro desconhecidas passam para o Python verbatim: .append, .pop, .sort, .reverse, .insert, .remove, .index, .count, .extend, .clear.
Dicts e sets
let user = {name: "Alice", age: 30}
print(user["name"]) // Alice
print(user.age) // 30
let unique = {1, 2, 2, 3, 3, 3}
print(unique) // {1, 2, 3}
Chaves de dict podem ser escritas sem aspas quando são identificadores: {name: "Alice"}.
Spread
let list1 = [1, 2]
let list2 = [3, 4]
let combined = [*list1, *list2, 5] // [1, 2, 3, 4, 5]
let defaults = {a: 1, b: 2}
let overrides = {b: 9}
let merged = {**defaults, **overrides} // {a: 1, b: 9}
Um spread nu em posição de valor é erro de parse; o spread é permitido apenas em um literal ou em um argumento de chamada.
Comprehensions
Comprehensions constroem uma coleção a partir de um iterável, com filtros opcionais:
let squares = [x * x for x in range(6)]
let evens = [x for x in range(20) if x % 2 == 0]
let lengths = {w: w.length() for w in ["ab", "xyz"]}
let unique_mods = {x % 3 for x in range(10)}
[0, 1, 4, 9, 16, 25]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
{'ab': 2, 'xyz': 3}
{0, 1, 2}
Múltiplas cláusulas for e if são suportadas e preservam a ordem da fonte. Comprehensions são eager; uma expressão geradora (e for x in xs) é lazy.
Strings
Strings são Unicode e imutáveis, com métodos de conveniência com nomes Aura que mapeiam para Python:
let text = "Hello, World"
print(text.to_upper()) // HELLO, WORLD
print(text.to_lower()) // hello, world
print(text.starts_with("He")) // true
print(text.ends_with("ld")) // true
print(text.trim()) // trims whitespace
print(text.slice(1, 4)) // ell
print(text.char_at(0)) // H
print(text.length()) // 12
Os aliases de Aura incluem starts_with/ends_with, to_upper/to_lower, trim/trim_left/trim_right, index_of, is_alpha, is_digit e mais.
Passando coleções para funções
Coleções são valores de referência: mutar uma dentro de uma função é visível ao chamador, enquanto reatribuir o parâmetro não é.
def mutate(xs) { xs.add(9) }
def reassign(x) { x = 9 }
def main() {
let a = [1]
mutate(a)
print(a) // [1, 9]
let n = 1
reassign(n)
print(n) // 1
}
O que você aprendeu
- Listas, dicts, sets, tuplas; indexação, slices e range-como-slice.
- Conveniências de tamanho/pertinência/mutação e passthrough para Python.
- Spreads e comprehensions.
- Coleções são referências; números e strings são valores.