• golang中,map作为函数参数是如何传递的


    当你声明一个map的时候:

    m := make(map[int]int)
    

    编译器会调用 runtime.makemap

    // makemap implements a Go map creation make(map[k]v, hint)
    // If the compiler has determined that the map or the first bucket
    // can be created on the stack, h and/or bucket may be non-nil.
    // If h != nil, the map can be created directly in h.
    // If bucket != nil, bucket can be used as the first bucket.
    func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap
    

    所以实际上是返回一个hmap的指针。

    如何验证呢?

    func main(){
    	m := make(map[int]int)
    	m[1] = 1
    	fmt.Printf("原始map的内存地址是:%p
    ", m)
    	modify(m)
    	fmt.Println("map值被修改了,新值为:", m)
    }
    
    func modify(m interface{}){
    	fmt.Printf("函数里接收到map的内存地址是:%p
    ", p)
    	m := p.(map[int]int)
    	m[1] = 2
    }
    

    输出结果:

    原始map的内存地址是:0xc00009e030
    函数里接收到map的内存地址是:0xc00009e030
    map值被修改了,新值为: map[1:2]
    

    在main函数中,m是个指针变量,它保存的值是:0xc00009e030。

    在modify函数中,m也是个指针变量,保存的值也是:0xc00009e030。

    说明初始化map后,返回的是指针变量,在函数之间,传递的是map的地址。

    map和channel是相似的。

    那么为什么不是 *map[key]value呢,这样不是更直观?

    Ian Taylor answered this recently in a golang-nuts 原话是:

    In the very early days what we call maps now were written as pointers, so you wrote *map[int]int. We moved away from that when we realized that no one ever wrote map without writing *map.

    意思是,一开始也是写作 *map[key]value,后来发现所有的map都是当作指针来用的,于是就省略简写了。

  • 相关阅读:
    Git常用命令清单笔记
    MySQL sql语句获取当前日期|时间|时间戳
    mysql-5.7.17.msi安装
    mysql sql语句大全
    解决Springboot集成ActivitiModel提示输入用户名密码的问题
    JAVA Spring MVC中各个filter的用法
    Spring Boot gradle 集成servlet/jsp 教程及示例
    RequireJS 参考文章
    Javascript模块化工具require.js教程
    Javascript模块化编程之路——(require.js)
  • 原文地址:https://www.cnblogs.com/zhouj-happy/p/10962500.html
Copyright © 2020-2023  润新知