http://wangzhezhe.github.io/blog/2016/01/22/golangmapaddressability-dot-md/

在golang中关于map可达性的问题(addresable?)

在go playground中有这样的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
) type Type struct {
A string
} func main() {
items := make(map[string]Type)
items["q"] = Type{}
items["q"].A = "abc"
fmt.Println(items)
}

这样在执行的时候会报一个常见的错误:cannot assign to items["q"].A

改变一下value的声明方式,之后再进行类似的操作就可以了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
) type Type struct {
A string
} func main() {
items := make(map[string]*Type)
items["q"] = &Type{}
items["q"].A = "abc"
fmt.Printf("%+v", items)
}

在golang设计的时候,map中的value值应该是地址不可达的,就是说直接取map中的元素的地址会报错,比如把上面例子中的main函数改成下边这样:

1
2
3
4
itemsb := make(map[string]Type)
itemsb["p"] = Type{3}
pointer := &itemsb["p"]
fmt.Println(pointer)

会报出cannot take the address of itemsb["p"]的错误。原因大致是因为,在golang中,一个容量不断增长的map可能会导致原来map中的一些元素发生rehashing,使得他们被重新分配到新的storage location上,这样可能会导致原先得到的address变得不可用。就是所谓的map member 的 not addresable。

正如这个答案中写的,map的indexing操作本来就是地址不可达的,这和golang中map的具体实现机制有关,golang中的map并没有保证它们的value值的地址是不可变的,因为value值的地址很有可能被重新分配,就像前面所说的那样。一个修改的办法就是把value值设置成为指针的形式,这样就相当于添加了一个额外的entry,即使真正需要的那个值的位置发生了变化,也可以redirection过去。以后使用map声明一个结构体的value值的时候,这一点要特别注意下。

对于slice的index操作就是地址可达的,对于map则是不可达的,总是使用map的时候要特别注意下。

??map is a reference to the map contents, but it does not hold references (unless it explicitly stores pointers).

相关参考:

https://golang.org/ref/spec#Address_operators

https://code.google.com/p/go/issues/detail?id=3117

https://groups.google.com/forum/#!topic/golang-nuts/4_pabWnsMp0

https://golang.org/ref/spec

http://stackoverflow.com/questions/13101298/calling-a-pointer-method-on-a-struct-in-a-map https://golang.org/ref/spec#Address_operators

http://stackoverflow.com/questions/16059038/can-not-assign-to-a-struct-member-from-map

首先要明确一下,在声明的时候&Type{}与Type{}的区别在哪里

currently map member并非是addressable的。

最新文章

  1. Python学习实践-----打印日历
  2. Indy FTP 警告:Only one TIdAntiFreeze can be active in an application
  3. export a java project to runable jar
  4. python操作mysql数据库的相关操作实例
  5. 【PHP面向对象(OOP)编程入门教程】13.访问类型(public,protected,private)
  6. [Android Training视频系列] 8.3 Dealing with Audio Output Hardware
  7. html之colspan && rowspan讲解
  8. 使用NuGet安装EntityFramework4.2
  9. 微信js接口自定义分享内容
  10. C# 之 遍历本地文件夹下的所有文件
  11. 【javascript模式】Chapter2: 基本 技巧
  12. NET 项目结构搭建
  13. 用static声明的函数和变量小结
  14. 数字音频处理的瑞士军刀sox的音效算法以及用法
  15. 前端 ------ 03 body标签中的相关标签
  16. Confluence 6 MySQL 3.x 字符集编码问题
  17. 【Beta Scrum】冲刺!5/5
  18. Mysql 实列结构-进程
  19. [转]web打印实现方案 Lodop6.034 使用方法总结
  20. webservice安全性浅谈

热门文章

  1. JS手风琴特效
  2. 常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类
  3. PTA 11-散列4 Hard Version (30分)
  4. ora-08104 该索引对象 159639 正在被联机建立或重建
  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
  6. 深入理解Java中的volatile关键字
  7. 单线程实现并发——协程,gevent模块
  8. linux监控平台搭建-内存
  9. 【BZOJ3529】【SDOI2014】数表 (莫比乌斯反演+树状数组)
  10. Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693