Eu sei que posso iterar sobre um mapa m
,
for k, v := range m { ... }
e procure uma chave, mas existe uma maneira mais eficiente de testar a existência de uma chave em um mapa?
Não consegui encontrar a resposta na especificação do idioma .
dictionary
go
go-map
grokus
fonte
fonte
Respostas:
Resposta em uma linha:
Explicação:
if
As instruções no Go podem incluir uma condição e uma instrução de inicialização. O exemplo acima usa os dois:inicializa duas variáveis -
val
receberá o valor de "foo" do mapa ou um "valor zero" (nesse caso, a string vazia) eok
receberá um bool que será definido comotrue
se "foo" estivesse realmente presente no mapaavalia
ok
, que serátrue
se "foo" estava no mapaSe "foo" estiver realmente presente no mapa, o corpo da
if
instrução será executado eval
será local nesse escopo.fonte
var val string = ""
permanecerá o mesmo,val, ok :=
cria uma nova variável local com o mesmo nome, visível apenas nesse bloco.if key in dict
.Além da especificação da linguagem de programação The Go , você deve ler Go eficaz . Na seção de mapas , eles dizem, entre outras coisas:
fonte
Pesquisou na lista de e -mails desagradáveis e encontrou uma solução publicada por Peter Froehlich em 15/11/2009.
Ou, de forma mais compacta,
Observe que, usando este formulário da
if
instrução, as variáveisvalue
eok
são visíveis apenas dentro dasif
condições.fonte
_, ok := dict["baz"]; ok
. A_
peça joga fora o valor em vez de criar uma variável temporária.Resposta curta
Exemplo
Aqui está um exemplo no Go Playground .
Resposta mais longa
De acordo com a seção Mapas do Effective Go :
fonte
Conforme observado por outras respostas, a solução geral é usar uma expressão de índice em uma atribuição do formulário especial:
Isso é legal e limpo. Porém, ele tem algumas restrições: deve ser uma atribuição de forma especial. A expressão do lado direito deve ser apenas a expressão do índice do mapa e a lista de expressões da esquerda deve conter exatamente 2 operandos, primeiro ao qual o tipo de valor é atribuível e um segundo ao qual um
bool
valor é atribuível. O primeiro valor do resultado desse formulário especial será o valor associado à chave e o segundo valor informará se há realmente uma entrada no mapa com a chave especificada (se a chave existir no mapa). A lista de expressões do lado esquerdo também pode conter o identificador em branco se um dos resultados não for necessário.É importante saber que, se o valor do mapa indexado é
nil
ou não contém a chave, a expressão do índice é avaliada como o valor zero do tipo de valor do mapa. Então, por exemplo:Experimente no Go Playground .
Portanto, se soubermos que não usamos o valor zero em nosso mapa, podemos tirar proveito disso.
Por exemplo, se o tipo de valor for
string
e sabemos que nunca armazenamos entradas no mapa em que o valor é a sequência vazia (valor zero para ostring
tipo), também podemos testar se a chave está no mapa comparando os itens não especiais forma da expressão de índice (resultado da) com o valor zero:Saída (experimente no Go Playground ):
Na prática, existem muitos casos em que não armazenamos o valor zero no mapa, portanto, isso pode ser usado com bastante frequência. Por exemplo, interfaces e tipos de função têm um valor zero
nil
, que geralmente não armazenamos em mapas. Portanto, é possível testar se uma chave está no mapa comparando-a comnil
.O uso dessa "técnica" também tem outra vantagem: você pode verificar a existência de várias chaves de maneira compacta (não é possível fazer isso com o formulário especial "vírgula ok"). Mais sobre isso: verifique se existe chave em vários mapas em uma condição
Obter o valor zero do tipo de valor ao indexar com uma chave inexistente também nos permite usar mapas com
bool
valores convenientemente como conjuntos . Por exemplo:Ele produz (experimente no Go Playground ):
Veja relacionados: Como posso criar uma matriz que contém seqüências de caracteres exclusivas?
fonte
T
dentrovar v, ok T = a[x]
? nãook
deve ser booleano?map[bool]bool
eT
ébool
, mas também funciona se o mapa for do tipomap[interface{}]bool
eT
éinterface{}
; além disso, ele também funciona com tipos personalizados que têmbool
como tipo subjacente, veja tudo no Go Playground . Portanto, como esse formulário é válido com vários tipos substituídosT
, é por isso que o generalT
é usado. Tipo deok
pode ser qualquer coisa à qual um tipo não digitadobool
pode ser atribuído.melhor caminho aqui
fonte
fonte
Então, vá em maps.go existe alguma restrição? verdadeiro não existe? falso
fonte
_, ok = m["somestring"]
deveria ser #=_, ok := m["somestring"]
É mencionado em "Expressões de índice" .
fonte
Uma atribuição de dois valores pode ser usada para essa finalidade. Verifique meu programa de amostra abaixo
fonte