Wiem, że mogę iterować po mapie m
,
for k, v := range m { ... }
i poszukaj klucza, ale czy istnieje bardziej skuteczny sposób testowania istnienia klucza na mapie?
Nie mogłem znaleźć odpowiedzi w specyfikacji języka .
dictionary
go
go-map
grokus
źródło
źródło
Odpowiedzi:
Odpowiedź w jednym wierszu:
Wyjaśnienie:
if
instrukcje w Go mogą zawierać zarówno warunek, jak i instrukcję inicjalizacji. W powyższym przykładzie wykorzystano oba:inicjuje dwie zmienne -
val
otrzyma wartość „foo” z mapy lub „wartość zerową” (w tym przypadku pusty ciąg znaków) iok
otrzyma wartość bool, która zostanie ustawiona,true
jeśli „foo” faktycznie byłoby obecne na mapieocenia
ok
, co będzie,true
jeśli „foo” było na mapieJeśli „foo” rzeczywiście jest obecne na mapie, treść
if
instrukcji zostanie wykonana ival
będzie lokalna w tym zakresie.źródło
var val string = ""
pozostanie taki sam,val, ok :=
tworzy nową zmienną lokalną o tej samej nazwie, która jest widoczna tylko w tym bloku.if key in dict
.Oprócz specyfikacji języka programowania The Go , powinieneś przeczytać Effective Go . W części dotyczącej map mówią między innymi:
źródło
Poszukałem na liście e-maili go-nuts i znalazłem rozwiązanie opublikowane przez Peter Froehlich w dniu 11/15/2009.
Lub, bardziej kompaktowo,
Uwaga: przy użyciu tej formy
if
instrukcji zmiennevalue
iok
są widoczne tylko wewnątrzif
warunków.źródło
_, ok := dict["baz"]; ok
._
Część rzuca wartość dala zamiast tworzenia zmiennej tymczasowej.Krótka odpowiedź
Przykład
Oto przykład na Go Playground .
Dłuższa odpowiedź
Według sekcji Effective Go w sekcji Mapy :
źródło
Jak zauważono w innych odpowiedziach, ogólnym rozwiązaniem jest użycie wyrażenia indeksu w przypisaniu specjalnej formy:
To jest miłe i czyste. Ma jednak pewne ograniczenia: musi to być specjalne zadanie. Wyrażenie po prawej stronie musi być tylko wyrażeniem indeksu mapy, a lista wyrażeń po lewej stronie musi zawierać dokładnie 2 operandy, po pierwsze, do którego można przypisać typ wartości, a po drugie, do którego
bool
można przypisać wartość. Pierwsza wartość wyniku tego specjalnego formularza będzie wartością powiązaną z kluczem, a druga wartość pokaże, czy rzeczywiście istnieje wpis na mapie z danym kluczem (jeśli klucz istnieje na mapie). Lista wyrażeń po lewej stronie może również zawierać pusty identyfikator, jeśli jeden z wyników nie jest potrzebny.Ważne jest, aby wiedzieć, że jeśli indeksowana wartość mapy zawiera
nil
lub nie zawiera klucza, wyrażenie indeksu ocenia na wartość zerową typu wartości mapy. Na przykład:Wypróbuj na placu zabaw Go .
Więc jeśli wiemy, że nie używamy wartości zerowej na naszej mapie, możemy to wykorzystać.
Na przykład, jeśli typem wartości jest
string
i wiemy, że nigdy nie przechowujemy pozycji na mapie, gdzie wartość jest pustym ciągiem (zerowa wartość dlastring
typu), możemy również sprawdzić, czy klucz znajduje się na mapie, porównując niespecjalne forma (indeksu) wyrażenia indeksu do wartości zerowej:Wyjście (wypróbuj na Go Playground ):
W praktyce istnieje wiele przypadków, w których nie przechowujemy wartości zerowej na mapie, więc można jej używać dość często. Na przykład interfejsy i typy funkcji mają zerową wartość
nil
, której często nie przechowujemy w mapach. Dlatego sprawdzenie, czy klucz znajduje się na mapie, można osiągnąć, porównując gonil
.Korzystanie z tej „techniki” ma jeszcze jedną zaletę: możesz sprawdzić istnienie wielu kluczy w kompaktowy sposób (nie możesz tego zrobić za pomocą specjalnego formularza „przecinek”). Więcej na ten temat: Sprawdź, czy klucz istnieje na wielu mapach w jednym stanie
Uzyskanie wartości zerowej typu wartości podczas indeksowania z nieistniejącym kluczem pozwala nam również
bool
wygodnie korzystać z map z wartościami jako zestawami . Na przykład:Wyprowadza (wypróbuj na Go Playground ):
Zobacz powiązane: Jak mogę utworzyć tablicę zawierającą unikalne ciągi?
źródło
T
wvar v, ok T = a[x]
środku nieok
musi być bool?map[bool]bool
iT
jestbool
, ale działa również, jeśli mapa jest typumap[interface{}]bool
iT
jestinterface{}
; ponadto działa również z niestandardowymi typami posiadającymibool
jako typ podstawowy, zobacz wszystkie na Go Playground . Ponieważ ten formularz jest prawidłowy, a wiele typów jest zastępowanychT
, dlategoT
używany jest ogólny . Typemok
może być dowolny obiekt, do którego można przypisać typ bez typubool
.lepszy sposób tutaj
źródło
źródło
Następnie uruchom mapy. Może coś istnieje? prawda nie istnieje? fałszywe
źródło
_, ok = m["somestring"]
powinno być=_, ok := m["somestring"]
Jest wspomniany w „Wyrażeniach indeksu” .
źródło
W tym celu można zastosować przypisanie dwóch wartości. Sprawdź mój przykładowy program poniżej
źródło