根据此提示:
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{}
答案 0 :(得分:2)
The Go Programming Language Specification
对于地图类型为M的地图:如果地图为零或不包含这样的地图, 项,a [x]是元素M的零值。
当通过声明为变量分配存储空间时 或调用new或创建新值时(通过 复合文字或make的调用,并且没有显式初始化 如果提供,则变量或值被赋予默认值。每个元素 这样的变量或值的类型为其类型设置为零值: 对于布尔值,为false;对于数字类型,为0;对于字符串,为“”;对于布尔值,为nil 指针,函数,接口,切片,通道和映射。
The Go Programming Language Specification
复合文字为结构,数组,切片和结构构造值 每次对其进行映射并创建新值。他们组成 字面量类型,后跟大括号绑定的元素列表。 每个元素可以可选地在对应的关键字之后。对于 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
变量声明创建一个或多个变量,并进行绑定 相应的标识符,并为每个标识符提供一个类型和一个 初始值。
如果给出了表达式列表,则变量将使用进行初始化 遵循分配规则的表达式。否则,每个 变量被初始化为其零值。
如果存在类型,则为每个变量指定该类型。除此以外, 给每个变量相应的初始化类型 值。
在您的示例中,您可以声明类型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")
}