go语言学习笔记(第2章)—类型部分

第2章:顺序编程 

GO语言被称为"更好的C语言"

1. 变量

1) 变量的声明GO语言引入了关键字  var,而类型信息放在变量名以后

例如: var v1 int

能够将多个变量声明放在一块儿,例如:
var (
        v1 int
        v2 string
)

2) 变量初始化有3种方式:
var v1 int = 10
var v2 = 10
v3 := 10

GO语言引入了新的符号(冒号和等号的组合  :=),用来表达同时进行变量声明和初始化的工做
但若是 := 左侧的变量已经被声明过了,再使用这个符号编译会出错

var i int
i := 2     //这样编译会报错

指定类型已经再也不是必须的,GO编译器能够从初始化表达式的右值推导出该变量应该声明为哪一种类型,这让GO语言看起来有点像动态类型语言(GO语言其实是彻彻底底的静态类型语言)

3) 声明变量以后的赋值过程
var v10 int
v10 = 123

GO提供了多重赋值功能
好比交换i和j变量的语言,以前的语言都须要引入一个中间变量,但GO能够这样作:
i, j = j, i

4) 匿名变量

2. 常量

在GO语言中,常量是指编译期间就已知且不可改变的值。常量能够是数值类型,布尔类型,字符串类型。

GO语言的字面常量更接近咱们天然语言中的常量概念,是无类型的。只要这个常量在相应类型的值域范围内,就能够做为该类型的常量。好比-12,能够赋值给int, uint, int32, float32...等

1) 常量定义
和C同样,定义常量也是使用 const关键字

若是定义常量时没有指定类型,那么它与字面常量同样,是无类型常量。

go语言学习笔记(第2章)—类型部分

2) 预约义常量
GO语言预约义了这些常量: true, false和iota
iota比较特殊,能够被认为是一个可被编译器修改的常量,在每个const关键字出现时被重置为0,而后在下一个const出现以前,每出现一次iota,其所表明的数字会自动增1

go语言学习笔记(第2章)—类型部分

若是两个const的赋值语言的表达式是同样的,那么能够省略后一个赋值表达式
go语言学习笔记(第2章)—类型部分

go语言学习笔记(第2章)—类型部分
上面两个声明是同样

3) 枚举
枚举指一系列相关的常量,GO语言不支持众多其余语言支持的enum关键字
在const后跟一对圆括号的方式定义一组常量,这种定义法在GO语言中一般用于定义枚举值。
go语言学习笔记(第2章)—类型部分

GO语言中,以大写字母开头的常量在包外可见,numberOfDays为包内私有,其余符号则可被其余包访问。

3.类型

GO语言内置如下基础类型:
布尔类型:bool
整型:int8, byte, int16, int, uint, uintptr
浮点类型:float32, float64
复数类型:complex64, complex128
字符串:string
字符类型:rune
错误类型:error

GO语言支持如下复合类型:
指针(pointer),数组(array),切片(slice),字典(map), 通道(chan)
结构体(struct), 接口(interface)

在这些基础类型之上GO还封装了下面几种类型:int, uint和uintptr等。这些类型的特色在于使用方便,但使用者不能对这些类型的长度作任何假设。对于常规的开发者来讲,用int和uint就能够了,不必用int8之类明确指定长度的类型,以避免致使移植困难。

1) 布尔类型
布尔类型不能接受其余类型的赋值,不支持自动或强制的类型转换。
go语言学习笔记(第2章)—类型部分

2) 整型
整型是全部编程语言里最基础的数据类型。
int 和 int32在GO语言里被认为是两种不一样的类型。编译器也不会帮你自动作类型转换
go语言学习笔记(第2章)—类型部分

使用强制类型转换能够解决这个编译错误:
go语言学习笔记(第2章)—类型部分

数值运算
GO语言支持下面的常规整数运算:+, -, *, /和%  %和在C语言中同样是求佘运算,好比:
5 % 3 //结果是2

比较运算
GO语言支持如下的几种比较运算符:>, <, ==, >=, <=和 != 

两个不一样类型的整型数不能直接比较,好比int8 类型的数和int类型的数不能直接比较,但各类类型的整型变量均可以直接与字面常量进行比较

go语言学习笔记(第2章)—类型部分

位运算
GO语言的大多数位运算符与C语言都比较相似,除了取反在C语言中是~x,而在GO语言中是^x

3) 浮点型
浮点型用于表示包含小数点的数据。
GO语言定义了两个类型float32, float64,其中float32等价于C语言中的float类型,float64等价于C语言的double类型
若是这样定义浮点型: fvalue2 := 12.0 
其类型将被自动设为float64,而无论赋给他的数字是否是用32位长度表示的

go语言学习笔记(第2章)—类型部分

由于浮点数不是一种精确的表达方式,因此像整型那样直接用==来判断两个浮点数是否相等是不可行的,这可能会致使不稳定的结果。替代方案就是相减后差小于0.00001

4) 字符串
在GO语言中,字符串也是一种基本类型。
go语言学习笔记(第2章)—类型部分
字符串的内容能够用相似于数组下标的方式获取, 字符串的内容不能在初始化后被修改

GO语言中的Printf()函数的用法与C语言运行库中的printf()函数一模一样。

GO语言只支持UTF-8和Unicode编码。对于其余编码,GO语言标准库并无内置的编码转换支持。不过,所幸的使咱们能够很容易基于iconv库用Cgo包装一个。

a. 字符串经常使用的操做有:字符串链接,字符串长度,取字符
go语言学习笔记(第2章)—类型部分

b. 字符串遍历
GO语言支持两种方式遍历字符串。

go语言学习笔记(第2章)—类型部分

以Unicode字符方式遍历时,每一个字符的类型是rune,而不是byte

4. 字符类型
在GO语言中支持两个字符类型,一个是byte,表明UTF-8字符串的单个字节的值;另外一个是rune,表明单个Unicode字符

5. 数组
数组是GO语言中最经常使用的数据结构之一。
go语言学习笔记(第2章)—类型部分
在GO语言中,数组的长度在定义后就不可更改,在声明时长度能够为一个常量或者一个常量表达式。
数组的长度是该数组类型的一个内置常量,能够用GO语言的内置函数len()来获取。

a. 元素访问
使用数组下标来访问数组中的元素,下标从0开始。 len(array) - 1则表示最后一个元素的下标。
GO语言提供了一个关键字 range,用于便捷地遍历容器中的元素。数组也是range支持的范围。
go语言学习笔记(第2章)—类型部分
range具备两个返回值,第一个返回值是元素的数组下标,第二个返回值是元素的值。

b. 值类型
在GO语言中数组是一个值类型,全部的值类型变量在赋值和做为参数传递时都将产生一次复制动做。若是将数组做为函数的参数类型,则在函数调用时该参数将发生数据赋值。所以,在函数体中没法修改传入的数组的内容,由于函数内操做的只是所传入数组的一个副本。

go语言学习笔记(第2章)—类型部分
modify()内操做的那个数组跟main()中传入的数组是两个不一样的实例。
若是要在函数内操做外部的数据结构,可使用数组切片来达成这个目标。

6. 数组切片
数组的特色:数组的长度在定义以后没法再次修改;数组是值类型,每次传递都将产生一份副本。

GO语言另外提供了数组切片(slice)来弥补数组的不足。初看起来,数组切片就像一个指向数组的指针,实际上它拥有本身的数据结构,而不只仅是个指针。数组切片的数据结构能够抽象为如下3个变量:
  • 一个指向原生数组的指针
  • 数组切片中的元素个数
  • 数组切片已分配的存储空间
从底层实现的角度看,数组切片实际上仍然使用数组来管理元素。基于数组,数组切片添加了一系列管理功能,能够随时动态扩充存放空间,而且能够被随意传递而不会致使所管理的元素被重复复制。

a. 建立数组切片
建立数组切片的方法主要有两种—基于数组和直接建立。

数组的建立以下:
go语言学习笔记(第2章)—类型部分

GO语言支持用  myArray[first:last]这样的方式来基于数组生成一个数组切片,并且这个用法还很灵活,好比如下都是合法的:
mySlice = myArray[:]
mySlice = myArray[:5]
mySlice = myArray[5:]

直接建立: 并不是必定要事先准备一个数组才能建立数组切片。GO语言提供的内置函数make()能够用于灵活地建立数组切片。
例子:
go语言学习笔记(第2章)—类型部分
固然,事实上还会有一个匿名数组被建立出来,只是不须要咱们操心而已。

b. 元素遍历
操做数组元素的全部方法都适用于数组切片,好比数组切片也能够按下标读写元素,用len()函数获取元素个数,并支持使用range关键字来快速遍历全部元素。
go语言学习笔记(第2章)—类型部分

c. 数组切片
可动态增减元素是数组切片比数组切片更为强大的功能。与数组相比,数组切片多了一个存储能力的概念,即元素个数和分配的空间能够是两个不一样的值。合理的设置存储能力的值,能够大幅下降数组切片内部从新分配内存和搬送内存块的频率,从而大大提升程序性能。

假设你明确知道当前建立的数组切片最多可能须要存储的元素个数为50,那么若是你设置的存储能力小于50,好比20,那么元素在超过20时,底层将会发生至少一次这样的动做:从新分配一块"够大"的内存,而且须要把内容从原来的内存块复制到新分配的内存块,这会产生比较明显的开销。给"够大"这两个字加上引号的缘由是系统并不知道多大才是够大,因此只是一个简单的猜想。好比,将原有的内存空间扩大两倍,但两倍并不必定够,因此以前提到的内存从新分配和内容复制的过程颇有可能发生屡次,从而明显下降系统的总体性能。但若是你知道最大是50而且一开始就设置存储能力为50,那么以后就不会发生这样很是消耗CPU的动做,从而达到空间换时间的效果。

数组切片支持GO语言内置的cap()函数和len()函数,cap()函数返回的是数组切片分配的空间大小,而len()函数返回的是数组切片中当前所存储的元素个数。

go语言学习笔记(第2章)—类型部分

在mySlice已包含的5个元素的后面继续新增元素,可使用append()函数
go语言学习笔记(第2章)—类型部分
函数append()的第二个参数是一个不定参数,咱们能够按本身需求添加若干个元素,甚至能够直接将一个数组切片追加到另外一个数组切片的末尾:
go语言学习笔记(第2章)—类型部分

须要注意的是,在第二个参数mySlice2后面加了3个点,即一个省略号,若是没有这个省略号的话,会有编译错误,由于按append()的语义,从第二个参数起全部的参数都是待附加的元素。由于mySlice中的元素类型是int,因此直接传递mySlice2是行不通的。加上省略号至关于把mySlice2包含的全部元素打散后传入。

上述调用等同于:
mySlice = append(mySlice, 8, 9, 10)

数组切片会自动处理存储空间不足的问题。若是追加的内容长度超过当前已分配的存储空间,数组切片会自动分配一块足够大的内存。

d. 基于数组切片建立数组切片
数组切片也能够基于另外一个数组切片建立。
go语言学习笔记(第2章)—类型部分
有意思的是,选择的oldSlice元素范围甚至能够超过所包含的元素个数,好比newSlice能够基于oldSlice的前6个元素建立,虽然oldSlice只包含5个元素。只要这个选择的范围不超过oldSlice存储能力(即cap()返回的值),那么这个建立程序就是合法的。newSlice中超出oldSlice元素的部分都会填上0

e. 内容复制
数组切片支持GO语言的另外一个内置函数copy(),用于将内容从一个数组切片复制到另外一个数组切片。若是加入的两个数组切片不同大,就会按其中较小的那个数组切片的元素个数进行复制。
go语言学习笔记(第2章)—类型部分

7. map
在GO语言中,使用map不须要引入任何库,而且用起来很方便。

go语言学习笔记(第2章)—类型部分
a. 变量声明
var myMap map[string] PersonInfo  
myMap是声明的map变量名,string是键的类型,PersonInfo则是其中所存放的值类型。

b. 建立
使用GO语言内置的函数make()来建立一个新的map
myMap  = make(map[string] PersonInfo)
也能够选择是否在建立时指定该map的初始存储能力,例如
myMap = make(map[string] PersonInfo, 100) //初始存储能力为100

也能够建立并初始化map
myMap = map[string] PersonInfo{
"1234": PersonInfo{"1", "Jack", "Room 101, ..."},
}

c. 元素赋值
myMap["1234"] = PersonInfo {"1", "Jack", "Room 101, ..."}

d. 元素删除
Go语言提供了一个内置函数delete(),用于删除容器内的元素
delete(myMap, "1234") //从myMap中删除键为"1234"的键值对,若是"1234"键不存在,这个调用将什么都不发生。若是传入的map变量值是nil,调用将致使程序抛出异常。

e. 元素查找
在GO语言中,map的查找功能设计的很精巧。
判断可否从map中获取一个值的常规作法是:
(1) 声明并初始化一个变量为空
(2) 试图从map中获取相应键的值到该变量中
(3) 判断该变量是否依旧为空,若是为空则表示map中没有包含该变量

这种作法比较啰嗦。在GO语言中,从map中查找一个特定的键,能够这样实现:
value, ok := myMap["1234"]
if ok {  //找到了
    //处理找到的value值
}

判断是否成功找到特定的键,不须要检查取到的值是否为nil,只需查看第二个返回值ok。

配合 := 操做符, 让你的代码没有多余的成分,看起来很是清晰易懂。
相关文章
相关标签/搜索