学过java的人都知道,java其实就8种基本类型:byte、short、int、long、float、double、char、boolean,但它有引用数据类型:字符串、数组、集合、类、接口等。
数组是具有相同数据类型的元素序列。 数组在声明中定义了固定的长度,因此不能扩展超过该长度。 数组声明为
让我们以代码举例如下
将变量city声明为5个字符串的数组,执行输出
输出结果
甚至,当您传递值时,可以使用省略号来使用隐式长度
输出结果
注意我们使用带Printf的fmt包以及如何使用%q“动词”来打印每个引用的元素。
如果我们使用Println或%s动词,我们将得到不同的结果
执行后输出如图
您还可以创建多维数组,示例代码:
输出结果
切片包装数组可为数据序列提供更通用,更强大和更方便的接口。 除了具有明确维数的项(例如转换矩阵)外,Go中的大多数数组编程都是使用切片而不是简单数组完成的。
切片包含对基础数组的引用,如果您将一个切片分配给另一个,则两个切片都引用同一数组。 如果函数采用slice参数,则对slice的元素所做的更改将对调用者可见,这类似于将指针传递给基础数组。
切片指向值数组,并且还包含长度。 切片可以调整大小,因为它们只是另一个数据结构之上的包装。
例如, []T is a slice with elements of type T 表示[] T是具有T类型元素的切片。
举个小例子
可以对切片进行切片,以创建一个指向相同数组的新切片值。表达式为
表示计算从start到end-1(含)的元素的一部分。
注意:start和end是表示索引的整数。
下面举个小demo
输出结果
除了通过立即传递值(切片文字)来创建切片之外,还可以使用make关键字创建切片。 您创建一个特定长度的空切片,然后填充每个条目。
输出结果:
它通过分配清零的数组并返回引用该数组的切片来工作。
可以通过append方式附加值到切片中
看输出结果
也可以同时附加多个值到切片中,示例代码同时包括两个城市郑洲和濮阳
输出结果
甚至您还可以使用省略号将切片附加到另一个切片
输出结果
注意: 省略号是该语言的内置功能,这意味着该元素是一个集合。 我们无法将字符串类型([] string)类型的元素附加到字符串切片中,只能附加字符串。 但是,在切片后使用省略号(...),表示要附加切片的每个元素。 因为我们要从另一个片段追加字符串,所以编译器将接受操作,因为类型是匹配的。
您显然无法将[] int类型的切片附加到[] string类型的另一个切片中。
切片也可以复制。 在这里,我们创建一个与other_cities长度相同的空切片copycities,并从other_cities复制到copycities中。
输出结果
您可以随时使用len检查切片的长度。
输出结果
切片的零值为nil。 无切片的长度和容量为0。
输出结果
Map 是一种无序的键值对的集合,Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
输出结果
当不使用上述map时,使用前必须使用make(不是新的)创建map。 nil映射为空,无法分配给它。
输出结果
3.1.1 在map中插入或更新元素
3.1.2 查询一个元素
3.1.3 删除一个元素
3.1.4 测试键是否存在并且有值
如果键在m中,则确定为true。 如果不是,则ok为false,elem为map元素类型的零值。 同样,从map中读取时(如果没有按键)则结果是map元素类型的零值。
综上合起来代码如下
输出结果
如何在map上进行迭代?您可以使用循环范围来迭代map, 因为映射是无序集合,所以此循环的值可能会有所不同。
输出结果
学过C(上学时第一门编程语言就是C)的人都知道, 指针是存放值内存地址的地方, 指针由*定义,根据数据类型定义指针,go也是这么玩的,声明格式如下
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。
&运算符可用于获取变量的地址。比如
而指针指向的值可以使用*运算符进行访问,示例如下
执行以上代码,输出结果
当一个指针被定义后没有分配到任何变量时,它的值为 nil,nil 指针也称为空指针。
nil在概念上和其它编程语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。空指针判断方式:
综上示例代码如下
输出结果
指针数组:简单点说它是一个数组,数组里面的每个元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。格式如下
ptr 为type指针数组,因此每个元素都指向了一个值,只是它的值是指针。
输出结果
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址。
指向指针的指针变量声明格式如下:
表示指向指针的指针变量为type。访问指向指针的指针变量值需要使用两个 * 号。
输出结果
go支持通过new函数创建指针, new函数将类型作为参数,并返回指向新分配的作为参数传递的类型的零值的指针。
输出结果
可以将指针传递给函数
输出结果
特别注意这这两种传参的区别
函数是基本的代码块,用于执行一个任务。
Go 语言最少有个 main() 函数。
你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。
函数声明告诉了编译器函数的名称,参数和返回类型。格式如下
函数定义解析:
message被定义为返回变量。 因此,定义的变量message将自动返回,而无需在最后的return语句中定义。
会改变原来的值,这很容易理解
您可以使用Golang中的…运算符来传递数组,也可以使用相同的…运算符来接收参数。
实际输出结果
没有名字的函数被称为匿名函数
golang的世界里没有像java一样有class类的概念,但它有像C语言一样的结构体Struct。
结构体是不同字段的类型化集合,结构体用于将数据分组在一起。
例如,如果我们要对User类型的数据进行分组,则定义一个user的属性,其中可以包括姓名,年龄,性别,所在城市。 可以使用以下语法定义结构
输出结果
输出结果
如图可以看到,现在可以使用点运算符user.describe调用该方法。 注意,接收者是一个指针。 使用指针,我们传递了对该值的引用,因此,如果对方法进行任何更改,它将反映在接收器user中。它也不会创建该对象的新副本,从而节省了内存。
请注意,在上面的示例中,age的值已更改,而name的值未更改,因为方法setName是接收者类型,而setAge是指针类型。
在同一包中,我们可以访问这些字段,如本示例所示, 由于main也在主程序包中,因此它可以引用u.password并检索存储在其中的值。 通常在结构体中具有未导出的字段,并通过导出的方法来访问它们。类比java里的访问权限private域,public访问方法。
以上程序输出结果
匿名仅创建新的结构变量,而不定义任何新的结构体类型。
以上程序代码中,定义了一个匿名结构变量emp, 正如我们已经提到的,该结构称为匿名结构,因为它仅创建一个新的结构变量emp,而不定义任何新的结构类型。
输出结果
比如我们经常网上购物时,填写订单接收地址(家里,公司,寄存点)
上面程序中的Person结构具有一个字段地址address,该字段地址又是一个结构体。
您可以使用&运算符获取指向结构体的指针
以上示例所示,Go使您可以直接通过指针访问结构体的字段。
输出结果
输出结果
Go编程提供了另一种称为接口的数据类型,它表示一组方法签名。
struct数据类型实现接口中定义的方法。
输出结果
和其他数据类型类似,通道使用前必须先创建,其初始值是 nil。创建通道的语法格式如下:
比如我们想创建了一个读写 int 类型,buffer 长度 100 的 channel c1,则如下:
通过此通道,我们可以发送int类型的数据。 我们可以在此通道中发送和接收数据
输出结果:
接收方通道等待,直到发送方将数据发送到通道。
在有些情况下,我们希望通过通道接收数据但不发送数据, 为此我们还可以创建一个单向通道。 让我们看一个简单的例子:
在上面的示例代码中,sc是go协程,该例程只能将消息发送到通道,但不能接收消息。
执行代码输出结果
在Golang中可以创建一个缓冲通道。 对于缓冲的通道,如果缓冲区已满,则将阻止发送到该通道的消息。 让我们看一个小例子
实际上超过缓冲最大值,要报错
那怎么办呢,还好有以下解决方法
输出结果
测验结果
Golang学习系列第三天:学习数组、切片、Map、结构体、指针、函数、接口类型、channel通道
原文:https://www.cnblogs.com/dongguangming/p/13311198.html