proc main(): void {
mut Str[dyn] a = ["x", "y"]
b := a // uma cópia, até onde se pode perceber
append(a, "z")
echo b // ["x", "y"]
}proc main(): void {
mut Str[dyn] a = ["x", "y"]
mut Str[dyn] b = a // um armazenamento, dois nomes
append(b, "z")
echo a // ["x", "y", "z"]
b = ["replaced"] // reatribui só b
echo a // ainda os três
}proc grow(vec: mut Str[dyn], tag: Str): void {
append(vec, tag)
}
proc main(): void {
mut Str[dyn] tags = ["bee"]
grow(tags, "hive")
echo tags // ["bee", "hive"]
}Todo valor em Hive se comporta como valor. Vincular um vetor, uma tabela, um mapa ou um registro a um segundo nome nunca deixa uma escrita por um aparecer no outro — o compilador copia onde precisa, em profundidade, e só pula a cópia onde consegue provar que ninguém perceberia. A exceção é pedida: quando os dois nomes são mut, mut b = a compartilha o armazenamento, então escrever por qualquer um alcança os dois, inclusive append. Reatribuir um deles, b = […], dá àquele nome um armazenamento próprio e deixa o outro com o que eles compartilhavam. Um escalar — um número, uma Str, ou um registro só de escalares — não tem armazenamento para compartilhar, então dois nomes mut para um deles são simplesmente dois valores.
Um parâmetro é uma cópia que o chamado não pode mudar, a menos que seja declarado nome: mut T. Esse é o único lugar em que o armazenamento atravessa uma chamada de propósito: o chamado escreve pela própria variável de quem chamou, então o argumento precisa ser uma variável mut ou um caminho para dentro de uma, como grow(tags) ou grow(box.items). Só um proc pode declarar um, que é o próximo slide.
Uma chamada iniciada numa thread própria com async recebe, em vez disso, uma cópia de cada argumento, feita antes de a thread começar, então os dois lados nunca escrevem no mesmo armazenamento.