Go语言基础:array、slice、make和new操作、map

uudou · · 2464 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

array

数组声明和赋值

go的数组声明跟C语言很相似,除了数组类型放在变量名后面【这点跟变量的声明一样】。
数组的定义格式:

//一维数组
var 数组名[n] 数组类型 //需要注意的是:'[n]'可以写成'[...]',go会自动根据元素个数来计算长度,
//我猜应该是编译的时候计算的吧
//二维数组
var 数组名[2][n]int{[n]数组类型{..},[n]数组类型{}}

数组的声明和赋值:

//一维数组
var ar = [5]byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := [5]byte {'a', 'b', 'c', 'd', 'e'}//注意这个只能是函数内部定义,也就是局部变量

//二维数组
var arr = [2][4]int{ [4]int{1, 2, 3}, [4]int{4, 5, 6} }
//可以省略{}中的[4]int
var arr = [2][4]int{ {1, 2, 3}, {4, 5, 6} }

数组容量和长度

Go中,函数cap()len()均输出数组的容量跟长度,不难发现数组的容量跟长度是一样的。

slice

Go的数组用的是C的思想,那么slice则用的是java的思想。slice在内存中的本质其实也是数组,体现为连续的内存块。但是它与数组又有不同,数组一旦定义好了,它的大小也就固定了;而slice的大小是可以变化的,但又不是java中真正意义上的动态数组,而是数组的引用,是一个引用类型。
slice的声明跟数组的声明一样,只是不需要长度。
slice的声明:

var fslice []int//注意这里没有长度,所以不要把它认为是数组哦
//同样也可以
slice := []int{1,2,3}

sliced的声明和赋值:

var ar = []byte {'a', 'b', 'c', 'd', 'e'}
//也可以
ar := []byte {'a', 'b', 'c', 'd', 'e'}//注意这个只能是函数内部定义,也就是局部变量

我们也可以从一个数组或者一个已经存在的slice中再次声明。slice 通过 array[i:j] 来获取,其中 i是数组的开始位置, j 是结束位置,但不包含 array[j] ,它的长度是 j-i

//声明一个数组
var Array_ori = [11]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}

//声明两个slice
var Slice_a,Slice_b[]byte

//Slice_a指向数组Array_ori,第2个元素`Array_ori[2-1]`开始,第5个元素`Array_ori[5-1]`结束
slice_a = Array_ori[2:5]

//slice1指向数组Slice_a,第3个元素`Slice_a[3-1]`开始,第5个元素`Slice_a[5-1]`结束
slice_b = Slice_a[3:5]//先自己想下会输出什么

其数据结构如下所示:
这里写图片描述

根据上图,不难推导出Array_ori, slice_a, slice_b的内容输出如下:

Array_ori[a b c d e f g h i j k]
slice_a[c d e]
slice_b[f g]

是不是对slice有种似曾相识的感觉,没错,感觉跟C的指针很像,一开始学的时候感觉有java的动态数组的思想,这会又有C的指针思想,宝宝好凌乱啊。

slice的几个内置函数

  • cap():slice的最大容量,上例中的 Slice_a和Slice_b的cap()值分别为8和5。正式由于Slice_a容量为8,所以给Slice_b的赋值是有效的
  • len():slice的长度,上例已有介绍,Slice_a和Slice_b的len()值分别为3和2
  • append():向 slice 里面追加一个或者多个元素,然后返回一个和 slice 一样类型的slice
  • copy():函数 copy 从源 slice 的 src 中复制元素到目标 dst ,并且返回复制的元素的个数

make和new操作

make跟new都可以用于内存分配。

  • new用于各种类型的内存分配,本质上跟java的new的功能是一样的。new(T)返回了一个指针,指向新分配的类型 T 的零值。
  • make只能用于给slice、map和channel类型的内存分配,并且返回一个有初始值(非零)的 T 类型,而不是指针 T。

map

map跟Pythoon的字典概念一样,凌乱了,又开始有python的思想了。关键是不懂python啊,不过没关系,后面我会学它的。

map的格式:

map[keyType] valueType

map的声明:

  • 使用map关键字: var map_variable map[keyType]valueType
  • 使用 make 函数,返回一个 map 给 map_variable:map_variable = make(map[keyType]valueType)

map的声明和赋值

var numbers map[string] int
// 另一种 map 的声明方式
numbers := make(map[string]int)

numbers["one"] = 1 //赋值 key是“one”,值是1
numbers["ten"] = 10 //赋值
numbers["three"] = 3

fmt.Println("第三个数字是: ", numbers["three"]) // 读取数据打印出来如:第三个数字是: 3

map注意事项:

  • map 是无序的,每次打印出来的 map 都会不一样,它不能通过 index 获取,而必须通过 key 获取
  • map 的长度是不固定的,也就是和 slice 一样,也是一种引用类型
  • 内置的 len 函数同样适用于 map ,返回 map 拥有的 key 的数量
  • map 的值可以很方便的修改,通过 numbers[“one”]=11 可以很容易的把 key 为 one的字典值改为 11
  • map 的初始化可以通过 key:val 的方式初始化值,同时 map 内置有判断是否存在 key 的方式;比如:map_variable := map[string]string{"a": "1", "b": "2", "c": "3"}
  • 通过 delete 删除 map 的元素,函数原型delete(map_variable, key)

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:uudou

查看原文:Go语言基础:array、slice、make和new操作、map

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2464 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传