Tipos compostos
Objetivo: declarar seus tipos com
decl(uma keyword para struct, enum e interface), casar sum types com pattern matching, e conhecer o variant-set.
decl: uma keyword, três formas
Seção intitulada “decl: uma keyword, três formas”decl declara struct, enum e interface; o corpo diz qual:
decl Point { x: int; y: int } // campos 'nome: tipo' → struct (produto)decl Shape { Circle(int); Square } // variantes 'Nome(...)' → enum (soma)decl Drawable { fn draw() -> []byte } // assinaturas 'fn ...' → interfaceOs três compartilham o ato de declarar um contrato, e o corpo desambigua. Membros separam-se
por ; ou Newline, nunca vírgula (vírgula é para grupos em (), como argumentos e tuplas).
Métodos são funções externas com receiver (estilo Go); a struct só guarda dados:
decl Dog { nome: string }fn (d: *Dog) speak() -> string { return "{{d.nome}}: woof" } // receiver '*Dog'
d := Dog{ nome: "Rex" } // literal: campos por ',' (grupo de valores)io.println(d.speak()) // UFCS: d.speak() ≡ speak(d)Construtores são funções associadas (receiver = só o tipo, sem nome):
fn (Dog) named(n: string) -> Dog { return Dog{ nome: n } }rex := Dog.named("Rex") // chamada por pontoSum types e pattern matching
Seção intitulada “Sum types e pattern matching”Enum com payload é um sum type; match o destrincha por variante, ligando os campos por posição:
decl Event { Tick; Click(int, int); Quit }
fn describe(e: Event) -> string { return match e { Tick => "tick" Click(x, y) => "click em ({{x}}, {{y}})" Quit => "quit" } // domínio fechado: todas as variantes, '_' seria erro}Enum sem payload é uma enumeração simples ou máquina de estados:
decl State { Idle; Running; Done }
fn step(s: State) -> State { return match s { Idle => Running Running => Done Done => Done }}Composição por @embeds (não há herança)
Seção intitulada “Composição por @embeds (não há herança)”Reúso é composição, com promoção declarada:
decl Animal {}fn (a: *Animal) speak() -> string { return "..." }
@embeds(Animal, methods)decl Cat { animal: Animal; nome: string }
c := Cat{ animal: Animal{}, nome: "Mia" }c.speak() // promovido: chama Animal.speak diretoVariant-set: um subconjunto de uma soma
Seção intitulada “Variant-set: um subconjunto de uma soma”Shape{Circle} é “um Shape, garantido Circle”: um conjunto de variantes. Em posição de tipo,
Nome{...} é variant-set; em posição de valor, Nome{...} é literal de struct (a posição separa):
fn so_clicks(e: Event{Click}) { ... } // aceita só a variante Click (checado no tipo)É a mesma mecânica dos error-sets do próximo capítulo: um domínio fechado que se sub-seta, com
{...} fechando o subconjunto.
alias dá um segundo nome transparente a um tipo que já existe (diferente de decl, que cria
tipo novo):
alias UUID = u128 // UUID É u128, intercambiávelPróximo: 04 · Erros