Ответ
Для проверки наличия ключа в map в Go используется специальная форма присваивания, которая возвращает два значения. Эта идиома называется "comma, ok".
package main
import "fmt"
func main() {
m := map[string]int{
"apple": 1,
"orange": 2,
}
// Пытаемся получить значение по ключу "apple"
val, ok := m["apple"]
if ok {
fmt.Printf("Ключ 'apple' существует, значение: %dn", val)
// Вывод: Ключ 'apple' существует, значение: 1
}
// Пытаемся получить значение по несуществующему ключу "banana"
val, ok = m["banana"]
if !ok {
fmt.Printf("Ключ 'banana' не существует. val имеет zero-value: %dn", val)
// Вывод: Ключ 'banana' не существует. val имеет zero-value: 0
}
}
Основные моменты:
-
Два возвращаемых значения: При доступе к
mapв формеval, ok := m[key], переменнаяokбудетtrue, если ключ существует, иfalseв противном случае. -
Проверка только наличия: Если само значение не нужно, можно использовать пустой идентификатор
_, чтобы его проигнорировать. Это самый эффективный способ.if _, ok := m["orange"]; ok { fmt.Println("Ключ 'orange' точно есть в map!") } -
Почему нельзя просто проверять значение? При обращении к несуществующему ключу
mapвсегда возвращает нулевое значение (zero-value) для типа своих значений. Если у васmap[string]int, то для отсутствующего ключа вернется0. Но0может быть и реальным значением, сохраненным вmap. Поэтому проверкаif m["key"] != 0ненадежна. -
Производительность Проверка наличия ключа в
map— это очень быстрая операция, в среднем занимающая константное время O(1).
Ответ 18+ 🔞
Так, слушай, смотри, блядь. Вот у тебя есть эта штука — map, да? Ну, типа словарь, где ключ к значению привязан. И тебе надо проверить, а есть ли там вообще этот ключ, или ты сейчас будешь в пустоту смотреть, как дурак.
Вот смотри, в Go для этого есть специальная, блядь, приёмка, называется "comma, ok". Выглядит как будто ты два значения из кармана достаёшь, а не одно.
package main
import "fmt"
func main() {
m := map[string]int{
"apple": 1,
"orange": 2,
}
// Пытаемся получить значение по ключу "apple"
val, ok := m["apple"]
if ok {
fmt.Printf("Ключ 'apple' существует, значение: %dn", val)
// Вывод: Ключ 'apple' существует, значение: 1
}
// Пытаемся получить значение по несуществующему ключу "banana"
val, ok = m["banana"]
if !ok {
fmt.Printf("Ключ 'banana' не существует. val имеет zero-value: %dn", val)
// Вывод: Ключ 'banana' не существует. val имеет zero-value: 0
}
}
Ну и что тут происходит, ёпта?
-
Два значения, Карл! Когда пишешь
val, ok := m[key], этаok— она как индикатор, блядь.true— ключ есть, всё пиздато.false— ключа нет, и ты сейчас держишь вvalполную хуйню, а именно нулевое значение типа. -
Если значение не нужно. А зачем тебе это значение, если ты просто проверить хочешь? Сука, используй пустой идентификатор
_, как мусорное ведро. Выкинул и забыл. Так даже эффективнее.if _, ok := m["orange"]; ok { fmt.Println("Ключ 'orange' точно есть в map!") } -
А почему просто не посмотреть на значение? О, это, блядь, классическая ловушка для распиздяев! Если ключа нет,
mapтебе всё равно вернёт ноль, пустую строку илиnil— в общем, zero-value. И что ты будешь делать, если у тебя вmapкак раз лежит ноль? Ты подумаешь, что ключа нет, а он есть! Пиздец, обоссаться можно. Поэтому толькоok. -
А это быстро? Да хуй с ним, с нулём! Главное — быстро? Быстро, блядь! Проверка ключа в
map— это операция за константное время, O(1). То есть неважно, там десять элементов или десять миллионов — скорость одна и та же, ёбушки-воробушки.