热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Golang中的array和slice以及map是怎样的

这篇文章将为大家详细讲解有关Golang中的array和slice以及map是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章

这篇文章将为大家详细讲解有关Golang中的array和slice以及map是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

一.Array

在Go语言中,数组是一个值类型(value type)

所有的值类型变量在赋值和作为参数传递时都将产生一个复制动作

如果作为函数的参数类型,则在函数调用时参数发生数据复制,在函数体中无法修改传入数组的内容

数组相等用 = != 比较,不能用 <>

1.声明&赋值

初始化

语法

代码如下:


var VarName [n]type     // n>=0

e.g.
var a [5]int //[0 0 0 0 0]
var c [2][3]int //二维

var b int = [5]int{1,2,3,4,5} //声明并初始化

a := [3]int{1,2,3}
b := [10]int{1,2,3} //前三个元素,其他为0
c := [20]int{19:1} //第20个元素初始化为1,其他默认0
d := [...]int{4,5,6} //自动计算长度
e := [...]int{0:1, 1:2, 19:3} //自动推断

二维数组

代码如下:


doubleArray := [2][4]int{[4]int{1,2,3,4}, [4]int{5,6,7,8}}
easyArray := [2][4]int{{1,2,3,4}, {1,2,3,4}}


多维 [...][n] 前者可推断,但是后者必须显示赋值
数组的长度是该数组类型的一个内置常量

arrLength := len(arr)
注意,数组长度也是类型的一部分,因此不同长度数组为不同类型(内置常量)

即[3]int和[4]int是不同类型,并且数组不能改变长度

数组之间的赋值是值的赋值,即当把一个数组作为参数传入函数的时候,传入的其实是该数组的副本(一次复制操作),而不是它的指针,如果要传入指针,使用slice

2.元素访问

代码如下:


for i:=0; i     fmt.Println(i, array[i])
}

for i, v := range array {
    fmt.Println(i, v)
}

可以用new创建数组

代码如下:


p := new([10]int)


返回一个指向数组的指针
注意区分

指向数组的指针

代码如下:


a := [100]int{}
var p *[100]int = &a


指针数组

代码如下:


x, y = 1, 2
a := [...]*int{&x, &y}

二.Slice

数组切片就像一个指向数组的指针,但更复杂,实际上它拥有自己的数据结构,而不仅仅是指针(指向原生数组的指针 + 数组切片中元素个数 + 数组切片已分配的存储空间)

一个引用类型,总是指向一个底层array,声明可以向array一样,只是不需要长度

slice就像一个结构体,包含三个元素

一个指针,指向数组中slice指定的开始位置
长度,即slice的长度
最大长度,也就是slice开始位置到数组的最后位置的长度
1.声明&赋值

通过array创建

代码如下:


var myArray [10]int = [10]int{1,2,3,4,5,6,7,8,9,10}
var mySlice []int = myArray[:5]

a := [5]int{1,2,3,4,5}
b := a[2:4]
b := a[:4]
b := a[2:]

从数组或已存在的slice再次声明

代码如下:


var ar [10]byte {&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;, &#39;g&#39;, &#39;h&#39;, &#39;i&#39;, &#39;j&#39;}

var a, b []byte
a = ar[2:5]
b = ar[3:5]

直接创建

代码如下:


myslice1 := make([]int, 5)
myslice2 := make([]int, 5, 10) //初始个数5,预留10个元素的存储空间
myslice3 := []int{1,2,3,4,5}

2.元素访问

代码如下:


for i:=0; i    fmt.Println(i, mySlice[i])
}

for i, v := range mySlice {
    fmt.Println(i, v)
}

3.其他操作

大小和容量

len获取slice的长度
cap获取slice的最大容量

动态增减元素

代码如下:


append想slice里面追加一个或者多个元素,然后返回一个和slice一样类型的slice

//append
mySlice = append(mySlice, 1, 2, 3) //增加三个元素
mySlice = append(mySlice, mySlice2) //增加另一个

注意,append会改变slice所引用的数组的内容,从而影响到引用统一数组的其他slice,
     但当slice中没有剩余空间,此时动态分配新的数组空间返回的slice数组指针将指向这个空间,
     而原数组的内容将保持不变,其他引用此数组的slice不受影响(坑,可能引入bug)

内容复制

代码如下:


copy,从源slice的src中复制到目标dst,并且返回复制元素的个数
copy(dst, source) //会按短的个数复制

slice1 := []int{1,2,3,4,5}
slice2 := []int{5,4,3}

copy(slice2, slice1) //复制slice1前三个 1 -> 2
copy(slice1, slice2) //复制slice2的前三个 2 -> 1

切片

代码如下:


默认开始位置0,ar[:n]等价于ar[0:n]
第二个序列默认是数组长度 ar[n:] 等价于 ar[n:len(ar)]
从一个数组直接获取slice,可以是ar[:]


slice是引用类型,所以当改变其中元素的时候,其他的所有引用都会改变

代码如下:


aSlice = array[3:7]
bslice = aSlice[:3]

三.Map

Python中字典的概念

map是无序的,长度不固定,内置的len可以用于map,可以方便的修改

1.声明&赋值

代码如下:


map[keyType]valueType

var m map[string] PersonInfo
m = make(map[string] personInfo[, 100])

var numbers map[string]int
or
numbers := make(map[string]int)
numbers["one"] = 1

初始化一个字典

2.元素访问

代码如下:


rating := map[string]float32 {"c":5, "Go":4.5}

csharpRating, ok := rating["C#"]
if ok {
    fmt.Println("get the value")
} else{
    fmt.Println("error")
}

3.基本操作

赋值

代码如下:


m["1234"] = PersonInfo{}


删除

代码如下:


delete(m, "1234")

四.其他

make和new操作

代码如下:


make用于内建类型(map,slice,channel) 的内存分配。

new用于各种类型的内存分配

new本质上和其他语言中同名函数一样, new(T)分配了零值填充的T类型的内存空间,并返回其地址,即一个*T类型的值 即,返回一个指针,指向新分配的类型T的零值

make(T, args),只能创建slice,map,channel,并返回一个有初始值(非零值)的T类型,而不是*T。 本质来讲,导致这三个类型有所不同的原因是,指向数据结构的引用在使用前必须被初始化

关于Golang中的array和slice以及map是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


推荐阅读
  • 认真一点学 Go:18. 并发
    收录于《Go基础系列》,作者:潇洒哥老苗。>>原文链接学到什么并发与并行的区别?什么是Goroutine?什么是通道?Goroutine如何通信?相关函数的使用?sel ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
author-avatar
崔颖2849464
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有