golang 深入理解map引用类型

理解指针

什么是指针?

指针是一种特殊的类型,指针变量的值是一个地址,该地址指向一个“指针类型”的变量

指针声明

var 指针变量名 *指针类型

示例

package main
import(
    "fmt"
)
func main() {
    var int_value = 10
    var int_ptr = &int_value
    fmt.Printf("The value of int_value %v\n", int_value)
    fmt.Printf("The pointer of int_value %p\n", &int_value)
    fmt.Printf("The value of int_ptr %v\n", int_ptr)
    fmt.Printf("The pointer of int_ptr %p\n", &int_ptr)
    var int_ptr_other *int
    int_ptr_other = int_ptr
    fmt.Printf("The value of int_ptr_other %v\n", int_ptr_other)
    fmt.Printf("The pointer of int_ptr_other %p\n", &int_ptr_other)
    // var string_ptr *string
    // string_ptr = &int_ptr 
    // cannot use &int_ptr (type **int) as type *string in assignment
}

输出

The value of int_value 10
The pointer of int_value 0xc210000018
The value of int_ptr 0xc210000018
The pointer of int_ptr 0xc210000020
The value of int_ptr_other 0xc210000018
The pointer of int_ptr_other 0xc210000028

内存布局

在这里插入图片描述

map 引用类型

示例

package main

import(
    "fmt"
    "reflect"
)

func main() {
    var m map[string]int
    // https://blog.golang.org/go-maps-in-action
    // Map types are reference types, like pointers or slices,  and so the value of m above is nil;
    // it doesn't point to an initialized map. A nil map behaves like an empty map when reading, 
    // but attempts to write to a nil map will cause a runtime panic; don't do that. 
    // To initialize a map, use the built in make function
    // Map类型 是引用类型,因此 m 的值为 nil
    fmt.Printf("type of un-initialized map reference %v\n", reflect.TypeOf(m))
    fmt.Printf("type of the pointer of map reference %v\n", reflect.TypeOf(&m))
    fmt.Printf("The un-initialized map reference %p\n", m)
    fmt.Printf("The pointer of map reference %p\n", &m)
    // The make function allocates and initializes a hash map data structure 
    // and returns a map value that points to it. The specifics of that data structure
    // are an implementation detail of the runtime and are not specified by the language itself.
    // make函数将会分配并初始化一个底层hash map结构,然后返回一个 map 值,该值指向底层的hash map结构
    m = make(map[string]int)
    fmt.Printf("The initialized map reference %p\n", m)
    fmt.Printf("type of initialized map reference %v\n", reflect.TypeOf(m))
    fmt.Printf("The pointer of map reference %p\n", &m)
    
}

输出

type of un-initialized map reference map[string]int
type of the pointer of map reference *map[string]int
The un-initialized map reference 0x0
The pointer of map reference 0xc210000018
The initialized map reference 0xc2100381e0
type of initialized map reference map[string]int
The pointer of map reference 0xc210000018

内存布局

在这里插入图片描述

map作为参数传递

示例

package main

import(
    "fmt"
)
// Map types are reference types
func main() {
    person := make(map[string]string)
    person["name"] = "nogo"
    fmt.Printf("person变量的内存地址是:%p\n", &person)
    fmt.Printf("原始map的内存地址是:%p\n", person)
    modify(person)
    fmt.Println("map值被修改了,新值为:",person)
}

func modify(person_inner map[string]string){
    fmt.Printf("person_inner变量的内存地址是:%p\n",&person_inner)
    fmt.Printf("函数内map的内存地址是:%p\n",person_inner)
    person_inner["age"] = "17"
 }

输出

person变量的内存地址是:0xc210000018
原始map的内存地址是:0xc2100381b0
person_inner变量的内存地址是:0xc210000020
函数内map的内存地址是:0xc2100381b0
map值被修改了,新值为: map[name:nogo age:17]

内存布局

在这里插入图片描述

解释

首先我们要明确:在 Go 中不存在引用传递,所有的参数传递都是值传递
person_inner 变量实际上是 person 变量的拷贝,其值也为指向底层hash map的指针,因此可以改变原生map的数据。

发布了88 篇原创文章 · 获赞 317 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/sunxianghuang/article/details/90637326