我知道我可以遍历映射m

for k, v := range m { ... }

寻找一个键,但是有没有更有效的方法来测试一个键在地图中的存在呢?


当前回答

简短的回答

_, exists := timeZone[tz]    // Just checks for key existence
val, exists := timeZone[tz]  // Checks for key existence and retrieves the value

例子

这是一个在Go Playground的例子。

再回答

根据Effective Go的地图部分:

An attempt to fetch a map value with a key that is not present in the map will return the zero value for the type of the entries in the map. For instance, if the map contains integers, looking up a non-existent key will return 0. Sometimes you need to distinguish a missing entry from a zero value. Is there an entry for "UTC" or is that the empty string because it's not in the map at all? You can discriminate with a form of multiple assignment. var seconds int var ok bool seconds, ok = timeZone[tz] For obvious reasons this is called the “comma ok” idiom. In this example, if tz is present, seconds will be set appropriately and ok will be true; if not, seconds will be set to zero and ok will be false. Here's a function that puts it together with a nice error report: func offset(tz string) int { if seconds, ok := timeZone[tz]; ok { return seconds } log.Println("unknown time zone:", tz) return 0 } To test for presence in the map without worrying about the actual value, you can use the blank identifier (_) in place of the usual variable for the value. _, present := timeZone[tz]

其他回答

    var empty struct{}
    var ok bool
    var m map[string]struct{}
    m = make(map[string]struct{})
    m["somestring"] = empty


    _, ok = m["somestring"]
    fmt.Println("somestring exists?", ok) 
    _, ok = m["not"]
    fmt.Println("not exists?", ok)

然后,去查地图,去 somestring存在吗?真正的 不存在?假

两个值的赋值可用于此目的。请检查下面的示例程序

package main

import (
    "fmt"
)

func main() {
    //creating a map with 3 key-value pairs
    sampleMap := map[string]int{"key1": 100, "key2": 500, "key3": 999}
    //A two value assignment can be used to check existence of a key.
    value, isKeyPresent := sampleMap["key2"]
    //isKeyPresent will be true if key present in sampleMap
    if isKeyPresent {
        //key exist
        fmt.Println("key present, value =  ", value)
    } else {
        //key does not exist
        fmt.Println("key does not exist")
    }
}

示例用法:循环遍历一个片,用于pairMap检查key是否存在。 它是一种算法,找出所有对相加到一个特定的和。

func findPairs(slice1 []int, sum int) {
    pairMap := make(map[int]int)
    for i, v := range slice1 {
        if valuei, ok := pairMap[v]; ok {
            fmt.Println("Pair Found", i, valuei)
        } else {
            pairMap[sum-v] = i
        }
    }
}

除了《Go编程语言规范》,你还应该阅读《Effective Go》。在地图的部分,他们说,除了别的以外:

An attempt to fetch a map value with a key that is not present in the map will return the zero value for the type of the entries in the map. For instance, if the map contains integers, looking up a non-existent key will return 0. A set can be implemented as a map with value type bool. Set the map entry to true to put the value in the set, and then test it by simple indexing. attended := map[string]bool{ "Ann": true, "Joe": true, ... } if attended[person] { // will be false if person is not in the map fmt.Println(person, "was at the meeting") } Sometimes you need to distinguish a missing entry from a zero value. Is there an entry for "UTC" or is that 0 because it's not in the map at all? You can discriminate with a form of multiple assignment. var seconds int var ok bool seconds, ok = timeZone[tz] For obvious reasons this is called the “comma ok” idiom. In this example, if tz is present, seconds will be set appropriately and ok will be true; if not, seconds will be set to zero and ok will be false. Here's a function that puts it together with a nice error report: func offset(tz string) int { if seconds, ok := timeZone[tz]; ok { return seconds } log.Println("unknown time zone:", tz) return 0 } To test for presence in the map without worrying about the actual value, you can use the blank identifier (_) in place of the usual variable for the value. _, present := timeZone[tz]

看看这段代码片段

nameMap := make(map[string]int)
nameMap["river"] = 33
v ,exist := nameMap["river"]
if exist {
    fmt.Println("exist ",v)
}