key
(chave) e procurar por ela rapidamente.chave
como a palavra e o valor
como a definição. E tem forma melhor de aprender sobre maps do que criar seu próprio dicionário?dicionario_test.go
map
e requer dois tipos. O primeiro é o tipo da chave, que é escrito dentro de []
. O segundo é o tipo do valor, que vai logo após o []
.go test
, o compilador vai falhar com ./dicionario_test.go:8:9: undefined: Busca
.dicionario.go
:dicionario_test.go:12: resultado '', esperado 'isso é apenas um teste', dado 'teste'
.map[chave]
.comparaStrings
para tornar a implementação mais genérica.Busca
em um método.dicionario_test.go
:Dicionario
, que ainda não definimos. Depois disso, chamamos Busca
da instância de Dicionario
.comparaStrings
.dicionario.go
:Dicionario
que trabalha em cima da abstração de map
. Com o tipo personalizado definido, podemos criar o método Busca
.Error
..Error()
, o que podemos fazer quando passarmos para a asserção. Também estamos protegendo o comparaStrings
com if
para certificar que não chamemos .Error()
quando o erro for nil
../dicionario_test.go:18:10: assignment mismatch: 2 variables but 1 values
incompatibilidade de atribuição: 2 variáveis, mas 1 valor
dicionario_test.go:22: expected to get an error.
erro esperado.
Busca
extraindo-o para dentro de uma variável. Isso também nos permite ter um teste melhor.ErrNaoEncontrado
para que nosso teste não falhe se mudarmos o texto do erro no futuro.Busca
para tornar a validação do dicionário um pouco mais fácil.dicionario.go
map
é um tipo referência. Isso significa que ele contém uma referência à estrutura de dado que estamos utilizando, assim como um ponteiro. Logo, quando criamos passamos o map como parâmetro, estamos alterando o map original e não sua cópia. A estrutura de dados utilizada é uma tabela de dispersão
ou mapa de hash
, e você pode ler mais sobre aqui.nil
. Um map nil
se comporta como um map vazio durante a leitura, mas tentar inserir coisas em um map nil
gera um panic em tempo de execução. Você pode saber mais sobre maps aqui (em inglês).make
para criar um map para você:hash map
vazio e apontam um dicionario
para ele. Assim, nos certificamos que você nunca vai obter um panic em tempo de execução.Adiciona
está bom. No entanto, não consideramos o que acontece quando o valor que estamos tentando adicionar já existe!Adiciona
não deve modificar valores existentes. Só deve adicionar palavras novas ao nosso dicionário.Adiciona
devolver um erro, que estamos validando com uma nova variável de erro, ErrPalavraExistente
. Também modificamos o teste anterior para verificar um erro nil
.Adiciona
.usado como valor
dicionario.go
:nil
.switch
para coincidir com o erro. Usar o switch
dessa forma dá uma segurança a mais, no caso de Busca
retornar um erro diferente de ErrNaoEncontrado
.ErrDicionario
que implementa a interface error
. Você pode ler mais sobre nesse artigo excelente escrito por Dave Cheney (em inglês). Resumindo, isso torna os erros mais reutilizáveis e imutáveis.Atualiza
a definição de uma palavra.Atualiza
é bem parecido com Adiciona
e será nossa próxima implementação.dicionario.Atualiza não definido (tipo Dicionario não tem nenhum campo ou método chamado Atualiza
Adiciona
. Logo, vamos implementar algo bem parecido com Adiciona
.Adiciona
. Se passarmos uma palavra nova, Atualiza
vai adicioná-la no dicionário.Atualiza
para retornar um valor error
.nil
.Adiciona
, com exceção de que trocamos quando atualizamos o dicionario
e quando retornamos um erro.ErrNaoEncontrado
e não criar um novo erro. No entanto, geralmente é melhor ter um erro preciso para quando uma atualização falhar.Você pode redirecionar o usuário quando oErrNaoEncontrado
é encontrado, mas mostrar uma mensagem de erro só quandoErrPalavraInexistente
é encontrado.
Deleta
uma palavra no dicionário.Dicionario
com uma palavra e depois verifica se a palavra foi removida.go test
obtemos:dicionario.Deleta não definido (tipo Dicionario não tem campo ou método Deleta)
delete
que funciona em maps. Ela leva dois argumentos: o primeiro é o map e o segundo é a chave a ser removida.delete
não retorna nada, e baseamos nosso método Deleta
nesse conceito. Já que deletar um valor não tem nenhum efeito, diferentemente dos nossos métodos Atualiza
e Adiciona
, não precisamos complicar a API com erros.