如果地图中未包含某些内容,则返回值取什么值?

时间:2018-10-27 19:28:21

标签: go

根据此提示:

How to check if a map contains a key in go?

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

很好,但是为什么我们不能这样做:

val, ok := m["foo"]

if val == nil {   // cannot compare val to nil

}

我收到一个编译错误,说我无法将val与nil比较,但是val有什么值?我可以将它与什么进行比较以确定它是否存在?

m的类型如下:

type m map[string]struct{}

2 个答案:

答案 0 :(得分:2)

  

The Go Programming Language Specification

     

Index expressions

     

对于地图类型为M的地图:如果地图为零或不包含这样的地图,   项,a [x]是元素M的零值。

     

The zero value

     

当通过声明为变量分配存储空间时   或调用new或创建新值时(通过   复合文字或make的调用,并且没有显式初始化   如果提供,则变量或值被赋予默认值。每个元素   这样的变量或值的类型为其类型设置为零值:   对于布尔值,为false;对于数字类型,为0;对于字符串,为“”;对于布尔值,为nil   指针,函数,接口,切片,通道和映射。


  

The Go Programming Language Specification

     

Composite literals

     

复合文字为结构,数组,切片和结构构造值   每次对其进行映射并创建新值。他们组成   字面量类型,后跟大括号绑定的元素列表。   每个元素可以可选地在对应的关键字之后。对于   struct文字适用以下规则:

     

文字可以省略元素列表;这样的字面值等于   类型为零。

在您的示例中,键入struct{},从复合文字struct{}{}中省略元素列表,以零值表示。

例如,

package main

import "fmt"

func main() {
    m := map[string]struct{}{}
    val, ok := m["foo"]
    fmt.Printf("%T %v\n", val, val)
    if val == struct{}{} {
        fmt.Println("==", val, ok)
    }
}

游乐场:https://play.golang.org/p/44D_ZfFDA77

输出:

struct {} {}
== {} false

  

The Go Programming Language Specification

     

Variable declarations

     

变量声明创建一个或多个变量,并进行绑定   相应的标识符,并为每个标识符提供一个类型和一个   初始值。

     

如果给出了表达式列表,则变量将使用进行初始化   遵循分配规则的表达式。否则,每个   变量被初始化为其零值。

     

如果存在类型,则为每个变量指定该类型。除此以外,   给每个变量相应的初始化类型   值。

在您的示例中,您可以声明类型struct{}的没有初始值的变量,该变量将初始化为struct{}类型的零值。

例如,

package main

import "fmt"

func main() {
    m := map[string]struct{}{}
    val, ok := m["foo"]
    fmt.Printf("%T %v\n", val, val)
    var zeroValue struct{}
    if val == zeroValue {
        fmt.Println("==", val, ok)
    }
}

游乐场:https://play.golang.org/p/_XcSCEeEKJV

输出:

struct {} {}
== {} false

答案 1 :(得分:-1)

您当然可以做上面的事情。与nil比较取决于map中具有的值的类型。如果其interface{}可以与nil进行比较:

m := map[string]interface{}{}

val, _ := m["foo"]

if val == nil {
    fmt.Println("no index")
}