复合数据类型
复合数据类型
主要内容
-
重点介绍以下四种常用复合数据类型:
- 数组
- slice
- map
- 结构体
数组和结构体的长度是固定的;slice和map都是动态数据结构,它们的长度在元素添加到结构体中时可以动态增长
使用这些数据类型构成的结构化数据编码为json数据,从json数据转换为结构化数据
数组
数组是一个由固定长度且多个相同数据类型元素的序列。因此,无法添加或者删除元素。
声明方式:
// 第一种声明,初始化方式
var q [3]int = [3]int{1, 2, 3}
// 第二种:...表示数组的长度由初始化元素的个数决定
q := [...]int{1, 2, 3}
数组的长度也是数组类型的一部分
// [3]int和[4]int是两种不同的数组类型
q := [3]int{1, 2, 3}
// 编译报错,理由如上
q = [4]int{1, 2, 3, 4}
数组初始化:
// 初始化索引的顺序是无关紧要的
type Currency int
const (
USD Currency = iota // 美元
EUR // 欧元
GBP // 英镑
RMB // 人民币
)
symbol := [...]string{USD: "$", EUR: "€", GBP: "£", RMB: "¥"}
fmt.Println(RMB, symbol[RMB])
// 定义了一个含有100个元素的数组r,最后一个元素被初始化为-1,其它元素都是用0初始化。
r := [...]int{99: -1}
数组间的比较:数组类型和元素类型确定能不能比较;元素相等决定数组相等
a := [2]int{1, 2}
b := [...]int{1, 2}
c := [2]int{1, 3}
// a与b数组类型相同,元素类型相同,可比较
// a与b的各个元素相等,则a与b相等
// a与c,b与c,数组类型相同,元素类型相同,元素不相等
fmt.Println(a == b, a == c, b == c) // "true false false"
d := [3]int{1, 2}
// 编译错误,数组类型不同,不能比较
fmt.Println(a == d)
函数调用参数传递:Go把数组和其他的类型都看成值传递,而在其他语言中,数组是隐式的使用引用传递。
显式地传入一个数组指针,那样的话函数通过指针对数组的任何修改都可以直接反馈到调用者。
func zero(ptr *[32]byte) {
// ptr是指针变量,使用range只返回一个索引?
for i := range ptr {
// 将ptr数组清零
ptr[i] = 0
}
}
// 另一种清零写法
func zero(ptr *[32]byte) {
// [32]byte{}生成一个有你32字节元素的数组
// 数组中每个元素的值是字节类型的零值,即0.
//
*ptr = [32]byte{}
}
使用指针:1.高效。 2.允许被调函数修改调用方数组中的元素。
slice
Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。
slice的底层是数组,一个底层数组可以对应多个slice。
months是底层数组,Q2和summer是slice。
slice 属性:
- 指针:指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素
- 长度:slice中元素的个数
- 容量:一般是从slice的**开始位置**到**底层数据的结尾位置**
slice操作符:左闭右开
// s即序列或底层数组。引用了s的i到j-1索引位置的元素
// 切片长度为:j-i
s[i:j]
// 引用了s的位置i到最后一个索引的元素
s[i:]
// 引用了s从0到j-1索引的元素。
s[:j]
// 引用整个数组
s[:]
引用异常:panic异常和slice扩容
// 根据上图的显示,months有13个元素。
// 初始化时,使用了 索引号:值的方式初始化。
months := [...]string{1: "January", /* ... */, 12: "December"}
// summer引用了months数组的6-8的元素。
// 其中指针指向6,长度为3,容量为7(指针开始位置为6,底层数组的结束位置为12.)
summer := months[6:9]
// panic 异常,引用超过了被引用对象summer的容量。导致宕机
fmt.Println(summer[:20])
// endlessSummer的引用超出了被引用对象summer的长度3。
// 因此endlessSummer**长度**会扩展到5.应用也会变为
// 从6-11
endlessSummer := summer[:5]
数组与slice初始化一点区别:
// 数组有固定长度
a := [...]int {0,1,2,3,4,5}
// slice无固定长度
s := []int{0,1,2,3,4,5}
slice无法直接使用==
做比较:slice的元素是非直接的,它可以包含自身;底层数组元素改变,同一个slice在不同的时间会有不同的元素。
slice允许的比较操作:和nil比较。
检查slice为空:使用len(s) == 0,而非 s==nil
make创建slie:
// 长度和容量相等
make([]T, len)
// 指定长度和容量
make([]T, len, cap)
上一篇: 编程初学者入门7_公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。(复习冒泡排序+C、Java中局部变量不赋值不能使用))
下一篇: c#中泛型的学习
推荐阅读
-
JavaEE基础day02 1.定义Java中的变量 四类八种 2.变量定义和使用的注意事项 3.数据类型的转换、强制数据类型转换4.算数运算符、比较运算符、逻辑运算符、赋值运算符、三元运算符
-
typescript之数据类型及函数、传参、重载
-
Java & Groovy & Scala & Kotlin - 05.数据类型
-
jQuery中的复合选择器如何使用
-
MySQL 数据类型的最优选择
-
分享下php5类中三种数据类型的区别,php5数据类型
-
php入门教程之数值型数据类型详解_PHP教程
-
对text数据类型不支持代码页转换 从: 1252 到: 936
-
分享下php5类中三种数据类型的区别,php5数据类型_PHP教程
-
PHP中数据类型转换的三种方式,数据类型三种方式_PHP教程