【问题标题】:How to initialise a map of maps [duplicate]如何初始化地图的地图[重复]
【发布时间】:2021-10-04 04:48:32
【问题描述】:

我想按国家和城市计算 IP 地址的地理位置。预期的输出是这样的:

$ cat ips.txt | ./geoips
United States  42
    Washington 21
    New York   21
China          10
    Beijing    10

我想出了这段代码,它使用地图的地图来保持计数:

func main() {
    ips := parseIPs(getIPs())

    counts := make(map[string]map[string]int)

    for _, ip := range ips {
        g := &checkip.Geo{}
        _, err := g.Check(ip)
        if err != nil {
            log.Printf("while getting geolocation: %v", err)
            continue
        }
        counts[g.Country][g.City]++
    }

    fmt.Printf("%v\n", counts)
}

当我构建并运行它时出现错误:

$ cat ips.txt | ./geoips
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
    /Users/xxx/geoips/main.go:30 +0x245

我知道问题是第二张地图没有初始化。我该怎么做?

或者有没有更好的方法来保持计数?

【问题讨论】:

    标签: dictionary go


    【解决方案1】:

    好的,我想明白了:

            // The following three lines fix the "assignment
            // to entry in nil map" runtime error.
            if _, ok := counts[g.Country]; !ok {
                counts[g.Country] = make(map[string]int)
            }
            counts[g.Country][g.City]++
    

    【讨论】:

    • 这里有个bug:如果一个国家有多个城市,你每次都会重新创建这个国家的地图,删除之前所做的一切。更好的方法是检查 counts[g.Country] == nil 是否:如果是,则制作 map[string]int。否则,你可以添加进去。
    • 感谢@NathanaelC.,已修复。虽然我用ok而不是nil
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    相关资源
    最近更新 更多