Open
Description
- 下面的代码输出是什么
// a
type person struct {
name string
}
func main() {
var m map[person]int
p := person{"mike"}
fmt.Println(m[p])
}
// b
func main() {
s := make(map[string]int)
delete(s, "h")
fmt.Println(s["h"])
}
输出:都是0
解析:打印一个 map
中不存在的值时,返回元素类型的零值。删除 map
不存在的键值对时,不会报错。
- 下面代码中
A, B
两处应该怎么修改才能顺利编译
func main() {
var m map[string]int //A
m["a"] = 1
if v := m["b"]; v != nil { //B
fmt.Println(v)
}
}
解析:A
处只进行了map
声明,不能直接赋值,需要使用make()
或者字面量的方式直接初始化map
,所以应该改为m := make(map[string]int)
;B
处改为v,k := m["b"]
当 key
为 b
的元素不存在的时候,v
会返回值类型对应的零值,k
返回 false
。
- 下面代码能正常通过编译吗
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
}
解析:编译错误。对于类似 X = Y
的赋值操作,必须知道 X
的地址,才能够将 Y
的值赋给 X
,但 go
中的 map
的 value
本身是不可寻址的。
有两个解决方法:
- 使用临时变量
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
tmp := m["foo"]
tmp.x = 4
m["foo"] = tmp
fmt.Println(m["foo"].x)
}
- 修改数据结构
type Math struct {
x, y int
}
var m = map[string]*Math{
"foo": &Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
fmt.Printf("%#v", m["foo"]) // %#v 格式化输出详细信息
}
- 下面这段代码存在什么问题
type Param map[string]interface{}
type Show struct {
*Param
}
func main() {
s := new(Show)
s.Param["day"] = 2
}
解析:map
需要初始化才能使用;指针不支持索引。
修复代码如下:
func main() {
s := new(Show)
p := make(Param)
p["day"] = 2
s.Param = &p
tmp := *s.Param
fmt.Println(tmp["day"])
}
- 下面代码有什么问题
func main() {
m := make(map[string]int,2)
cap(m)
}
解析:使用 cap()
获取 map
的容量。
使用 make
创建 map
变量时可以指定第二个参数,不过会被忽略;
cap()
函数适用于数组、数组指针、slice
和 channel
,不适用于 map
,可以使用 len()
返回 map
的元素个数。
- 下面代码输出什么
type T struct {
n int
}
func main() {
m := make(map[int]T)
m[0].n = 1
fmt.Println(m[0].n)
}
解析:编译错误。map[key]struct
中 struct
是不可寻址的,所以无法直接赋值。