详解Go中Map类型和Slice类型的传递
作者:snowInPluto 发布时间:2024-04-23 09:47:03
关于 Go 中 Map 类型和 Slice 类型的传递
Map 类型
先看例子 m1:
func main() {
m := make(map[int]int)
mdMap(m)
fmt.Println(m)
}
func mdMap(m map[int]int) {
m[1] = 100
m[2] = 200
}
结果是
map[2:200 1:100]
我们再修改如下 m2:
func main() {
var m map[int]int
mdMap(m)
fmt.Println(m)
}
func mdMap(m map[int]int) {
m = make(map[int]int)
m[1] = 100
m[2] = 200
}
发现结果变成了
map[]
要理解这个问题,需要明确在 Go 中不存在引用传递,所有的参数传递都是值传递。
现在再来分析下,如图:
可能有些人会有疑问,为什么途中的 m 像是一个指针呢。查看官方的 Blog 中有写:
Map types are reference types, like pointers or slices, ...
这边说 Map 类型是引用类型,像是指针或是 Slice(切片)。所以我们基本上可以把它当作是指针来看待(注意,只是近似,或者说其中含有指针,其内部仍然含有其他信息,这里只是为了便于理解),只不过这个指针有些特殊罢了。
m1 中,当调用 mdMap 方法时重新开辟了内存,将 m 的内容,也就是 map 的地址拷贝入了 m',所以此时当操作 map 时,m 和 m' 所指向的内存为同一块,就导致 m 的 map 发生了改变。
而在 m2 中,在调用 mdMap 之前,m 并未分配内存,也就是说并未指向任何的 map 内存区域。从未导致 m' 的 map 修改不能反馈到 m 上。
Slice 类型
现在看一下 Slice。
s1:
func main() {
s := make([]int, 2)
mdSlice(s)
fmt.Println(s)
}
func mdSlice(s []int) {
s[0] = 1
s[1] = 2
}
s2:
func main() {
var s []int
mdSlice(s)
fmt.Println(s)
}
func mdSlice(s []int) {
s = make([]int, 2)
s[0] = 1
s[1] = 2
}
不出所料:
s1 结果为
[1 2]
s2 为
[]
因为正如官方所说,Slice 类型与 Map 类型一样,类似于指针,Slice 中仍然含有长度等信息。
修改一下 s1,变成 s3:
func main() {
s := make([]int, 2)
mdSlice(s)
fmt.Println(s)
}
func mdSlice(s []int) {
s = append(s, 1)
s = append(s, 2)
}
不再修改 slice 原先的两个元素,而加上另外两个,结果为:
[0 0]
发现修改并没有反馈到原先的 slice 上。
这里我们需要把 slice 想象为特殊的指针,其已经保存了所指向内存区域长度,所以 append 之后的内存并不会反映到 main() 中:
那如何才能反映到 main() 中呢?没错,使用指向 Slice 的指针。
func mdSlice(s *[]int) {
*s = append(*s, 1)
*s = append(*s, 2)
}
内存如图所示:
注意本文中内存区域分配是否连续完全随机,不影响程序,只是为了图解清晰。
Chan 类型
Go 中 make 函数能创建的数据类型就 3 类:Slice, Map, Chan。不比多说,相比读者已经能想象 Chan 类型的内存模型了。的确如此,读者可以自己尝试,这边就不过多赘述了。(可以通通过 == nil 的比较来进行测试)。
来源:http://www.cnblogs.com/snowInPluto/p/7477365.html
猜你喜欢
- 前段时间我通过观察韩国网站和其他作品发现了普遍存在黄金分割这样一个规律,不过只跟色相有关,明度、纯度还没做研究,今天看到论坛一篇“网页配色之
- 关键字:js验证表单大全,用JS控制表单提交 ,javascript提交表单:目录:1:js 字符串长度限制、判断字符长度 、js限制输入、
- 一、Python操作PDF 13大库对比PDF(Portable Document Format)是一种便携文档格式,便于跨操作系统传播文档
- 我们可向函数传递动态参数,*args,**kwargs,首先我们来看*args,示例如下:1.show(*args)def show(*ar
- 创建测试数据:import pandas as pdimport numpy as np#Create a DataFramedf1 = {
- 以下是我这几天一直在用的几个命令,先记下来,以后会整理一份mysql详细的使用文档注:[]中代表名字,需要用库名或者表名替换显示所有的库:s
- 互联网上的每台计算机都有独一无二的编号,称为IP地址,每个合法的IP地址由“.”分开的4个数字组成,并且IP地址细分类型的话,可以分为“A”
- 1.安装1.1 创建虚拟环境mkdir myprojectcd myprojectpython3 -m venv venv1.2 进入虚拟环
- 文件内容:excel内容:代码:import xlrdimport jsonimport operatordef read_xlsx(fil
- 本文实例讲述了js显示世界时间的方法。分享给大家供大家参考,具体如下:<!DOCTYPE HTML PUBLIC "-//W
- 如下所示:#获得视频的格式videoCapture = cv2.VideoCapture('/home/lw/3661.mp4
- Null模式我想每个人都有一种经历,为了获取某属性,但是有时候属性是None,那么需要你做异常处理, 而假如你想节省这样的条件过滤的代码,可
- Python编程中类的概念可以比作是某种类型集合的描述,如“人类”可以被看作一个类,然后用人类这个类定义出每个具体的人——你、我、他等作为其
- 使用wordcloud模块,生成云图,测试文本为:Betty Botter bought some butter but she said
- #!/usr/bin/py2# -*- coding: utf-8 -*-#encoding=utf-8'''
- Python 相对路径报错:"No such file or directory"'原因及解决方法如果你取相对路
- 项目开发中hadoop一直装在虚拟机上,最近要迁移到服务器上。记录下迁移过程。一、为虚拟机添加一块新的硬盘虚拟机的初始硬盘只有30G,容不开
- 方法一通过斜率关系计算,公式如下图:需注意在求斜率时不要出现竖直情况,python计算会报错,但按理说应该可以计算出无穷的,此处先放这吧,等
- 这篇文章主要介绍了python文字和unicode/ascll相互转换函数及简单加密解密实现代码,下面我们来了解一下。import reim
- 在使用Dreamweaver制作主页的时候往往需要改变表格的高度。然而有时当我们拖动表格的边框,无论怎样拖动,等到放下鼠标,表格却又恢复到原