我知道我可以遍历映射m

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

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


当前回答

示例用法:循环遍历一个片,用于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-nuts电子邮件列表中搜索,找到了Peter Froehlich在2009年11月15日发布的解决方案。

package main

import "fmt"

func main() {
        dict := map[string]int {"foo" : 1, "bar" : 2}
        value, ok := dict["baz"]
        if ok {
                fmt.Println("value: ", value)
        } else {
                fmt.Println("key not found")
        }
}

或者更简洁地说,

if value, ok := dict["baz"]; ok {
    fmt.Println("value: ", value)
} else {
    fmt.Println("key not found")
}

注意,使用这种形式的if语句,value和ok变量只在if条件中可见。

    var d map[string]string
    value, ok := d["key"]
    if ok {
        fmt.Println("Key Present ", value)
    } else {
        fmt.Println(" Key Not Present ")
    }

下面是检查映射是否包含键的方法。

val, ok := myMap["foo"]
// If the key exists
if ok {
    // Do something
}

这将初始化两个变量。Val是映射中“foo”的值(如果存在),如果不存在则为“0值”(在本例中为空字符串)。Ok是bool类型,如果键存在,它将被设置为true。

如果愿意,可以将其缩短为一行代码。

if val, ok := myMap["foo"]; ok {
    //do something here
}

Go允许您在if语句中的条件(注意分号)之前放置初始化语句。这样做的结果是,ofval和ok的作用域将被限制在if语句的主体中,如果你只需要在那里访问它们,这是很有帮助的。

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

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")
    }
}

除了《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]