# Map面试题

关于golang面试题：摘自<https://goquiz.github.io/#subslice-grow>

Correct two mistakes in line A and B.

```
package main
​
func main() {
    var m map[string]int //A
    m["a"] = 1
    if v := m["b"]; v != nil { //B
        println(v)
    }
}
​
```

解惑：

A行，就这个申明不初始化，是没问题的，你可以读空map，但是不能写，你必须初始化后才能赋值。如果不初始化 map，那么就会创建一个 nil map。nil map 不能用来存放键值对。

改为: var m = make(map\[string]int)

这边顺便说下golang中的nil到底是怎么回事？

首先nil并不是golang的关键字，甚至nil还可以被赋值，不信的话你可以试一下，是可以通过编译的

在Golang中，如果你没有对一个变量进行赋值，那么会有一个默认的零值，Go的文档中说到，*nil是预定义的标识符，代表指针、通道、函数、接口、映射或切片的零值*，先看下下面的零值：

```
bool      -> false                              
numbers -> 0                                 
string    -> ""      
​
pointers -> nil
slices -> nil
maps -> nil
channels -> nil
functions -> nil
interfaces -> nil
```

这边稍带介绍下ponter和interface两个与nil的关系：

**Pointer**

```
    var p *int
    fmt.Println(p == nil)    // true
    *p = 1     //panic: runtime error: invalid memory address or nil pointer dereference
```

指针是指向内存地址的，如果对空指针进行赋值的话会报错。因为指针的零值是Nil所以比较判断会报true。空指针有个妙用（也不知道算不算妙用，我就觉得之前没见过），就是指针方法，指针方法就算指针是nil的情况下也能正常调用。例如下面的例子

```
type tree struct {
  v int
  l *tree
  r *tree
}
​
// 现在这个指针方法，就算t为nil也能被正常调用。
func (t *tree) Sum() int {
   if t == nil {
    return 0
  }
  return t.v + t.l.Sum() + t.r.Sum()
}
```

**interface**

interface并不是一个指针，它的底层实现由两部分组成，一个是类型，一个值，也就是类似于：(Type, Value)。只有当类型和值都是`nil`的时候，才等于`nil`。(这一点在判断interface是不是nil的时候很关键)

```
type  doError interface{
​
}
​
func testNilInterface() doError{
    var err *doError
    return err 
}
​
func main() {
    fmt.Println(testNilInterface() == nil)
}
```

结果：false.这边虽然声明了指针err，未初始化，其值是nil，但是interface的type不是空值，所以与nil是不相等。interface要类型和值都为nil,interface才会和nil相等，例如如下函数：

```
func testNilInterface1() doError{
    return nil
}
func main() {
    fmt.Println(testNilInterface1() == nil)
}
```

就会返回true了

B行，会报编译错误：cannot convert nil to type int，原因是，map中不存在key为b的键值对，就会返回nil，而nil不能强转为int

应该改为：

if v , ok:= m\["b"]; ok {...}

现在就算map没有b这个key，v也会被初始化为Int的零值就是0

参考资料：

<https://www.youtube.com/watch?v=ynoY2xz-F8s>\
csdn博客：<https://blog.csdn.net/u013276277>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zhounanjun.gitbook.io/nanjun/golang/map-mian-shi-ti.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
