94

When the following code:

m := make(map[string]string)
if m == nil {
    log.Fatal("map is empty")
}

is run, the log statement is not executed, while fmt.Println(m) indicates that the map is empty:

map[]
030
  • 10,842
  • 12
  • 78
  • 123
  • 2
    This question has a lot of upvote but I think there's a little misunderstanding here: a map can be `nil` or can be initialized and with 0 value inside that. This are two different situations! – Cirelli94 Mar 11 '20 at 13:47

2 Answers2

205

You can use len:

if len(m) == 0 {
    ....
}

From https://golang.org/ref/spec#Length_and_capacity

len(s) map[K]T map length (number of defined keys)

030
  • 10,842
  • 12
  • 78
  • 123
jacob
  • 4,656
  • 1
  • 23
  • 32
  • 24
    For those who is wondering about complexity it is O(1). Here's [implementation](https://github.com/golang/go/blob/5c11480631f5654e9e6937ff08c453660138c64d/src/runtime/map.go#L111). – Slava Bacherikov Aug 12 '18 at 13:57
2

The following example demonstrates both the nil check and the length check that can be used for checking if a map is empty

package main

import (
    "fmt"
)

func main() {
    a := new(map[int64]string)
    if *a == nil {
        fmt.Println("empty")
    }
    fmt.Println(len(*a))
}

Prints

empty
0
Mradul
  • 39
  • 4
  • `new(map[int64]string)` return a uninitialized pointer to a map. You can't use that to check if the map is empty. – super Nov 24 '20 at 17:26
  • 1
    @Mradul you don't need a pointer to a map or a slice: they're already pointers! – Alessandro Argentieri Sep 28 '21 at 14:50
  • @super Neither `a` nor `*a` are uninitialized. `new()` doesn't *initialize* the memory it allocates, but it *zeros* it. See https://go.dev/doc/effective_go#allocation_new The zero value of a map is equal to `nil`. In some aspects, it behaves like an empty map: you can check its size with `len()`, loop over it (won't execute loop body), delete an entry (won't do anything), print it (will print `map[]`), etc. Trying to add an entry will panic though. – jcsahnwaldt Reinstate Monica Dec 04 '22 at 14:19
  • P.S. Or maybe `*a` can be said to be uninitialized, but it's in a well-defined state and usable, e.g. for `len(*a)`. That's quite different from languages like C, where "uninitialized" means "completely unusable until you initialize it". – jcsahnwaldt Reinstate Monica Dec 04 '22 at 15:14