Я знаю, что могу перебрать карту m
,
for k, v := range m { ... }
и искать ключ, но есть ли более эффективный способ проверки существования ключа на карте?
Я не мог найти ответ в спецификации языка .
dictionary
go
go-map
grokus
источник
источник
Ответы:
Ответ в одну строку:
Объяснение:
if
операторы в Go могут включать как условие, так и оператор инициализации. В приведенном выше примере используются оба:инициализирует две переменные -
val
получит либо значение «foo» с карты, либо «нулевое значение» (в данном случае пустую строку) иok
получит значение bool, которое будет установлено в томtrue
случае, если «foo» действительно присутствовало на картеоценивает
ok
, что будет,true
если "foo" был на картеЕсли «foo» действительно присутствует на карте, тело
if
оператора будет выполнено иval
будет локальным для этой области.источник
var val string = ""
останется прежним,val, ok :=
создаст новую локальную переменную с тем же именем, которая видна только в этом блоке.if key in dict
.В дополнение к спецификации языка программирования Go вы должны прочитать Effective Go . В разделе о картах , среди прочего, говорится:
источник
Поиск по списку рассылок и поиск решения, размещенного Питером Фрёлихом 15.11.2009.
Или, более компактно,
Обратите внимание, что с помощью этой формы
if
заявления, тоvalue
иok
переменные видны только внутриif
условий.источник
_, ok := dict["baz"]; ok
._
Часть бросает значение прочь вместо создания временной переменной.Короткий ответ
пример
Вот пример на игровой площадке Go .
Более длинный ответ
В разделе « Карты » Effective Go :
источник
Как отмечено другими ответами, общее решение состоит в том, чтобы использовать индексное выражение в назначении специальной формы:
Это красиво и чисто. Однако у него есть некоторые ограничения: это должно быть присвоение специальной формы. Выражение в правой части должно быть только выражением индекса карты, а список выражений в левой части должен содержать ровно 2 операнда: первый, которому присваивается тип значения, и второй, которому
bool
присваивается значение. Первым значением результата этой специальной формы будет значение, связанное с ключом, а второе значение скажет, есть ли на карте запись с данным ключом (если ключ существует на карте). Список выражений в левой части также может содержать пустой идентификатор, если один из результатов не нужен.Важно знать, что если индексированное значение карты является
nil
или не содержит ключ, индексное выражение оценивается как нулевое значение типа значения карты. Так, например:Попробуйте это на игровой площадке Go .
Поэтому, если мы знаем, что мы не используем нулевое значение на нашей карте, мы можем воспользоваться этим.
Например, если типом значения является
string
, и мы знаем, что мы никогда не храним записи на карте, где значением является пустая строка (нулевое значение дляstring
типа), мы также можем проверить, находится ли ключ на карте, сравнивая не специальный форма (результат) выражения индекса до нулевого значения:Вывод (попробуйте на Go Playground ):
На практике во многих случаях мы не храним нулевое значение на карте, поэтому его можно использовать довольно часто. Например, интерфейсы и типы функций имеют нулевое значение
nil
, которое мы часто не храним в картах. Поэтому можно проверить, есть ли ключ на карте, сравнив его сnil
.Использование этой «техники» имеет и другое преимущество: вы можете компактно проверить наличие нескольких ключей (вы не можете сделать это с помощью специальной формы «запятая нормально»). Подробнее об этом: Проверьте, существует ли ключ на нескольких картах в одном условии
Получение нулевого значения типа значения при индексации с несуществующим ключом также позволяет нам
bool
удобно использовать карты со значениями в виде наборов . Например:Он выводит (попробуйте на Go Playground ):
Смотрите связанные: Как я могу создать массив, который содержит уникальные строки?
источник
T
внутриvar v, ok T = a[x]
? неok
должно быть бул?map[bool]bool
иT
естьbool
, но это также работает, если карта имеет типmap[interface{}]bool
иT
естьinterface{}
; Более того, он также работает с пользовательскими типами, имеющимиbool
базовый тип, смотрите все на Go Playground . Так как эта форма действительна с заменой нескольких типовT
, поэтому используется общееT
. Типok
может быть любым, для которого может быть назначен нетипизированныйbool
.лучший способ здесь
источник
источник
Затем запустите maps.go существует ли какая-нибудь строка? правда не существует? ложный
источник
_, ok = m["somestring"]
должно быть=_, ok := m["somestring"]
Упоминается в разделе «Индексные выражения» .
источник
Для этой цели можно использовать присвоение двух значений. Пожалуйста, проверьте мой пример программы ниже
источник