Go语言内置以下这些基础类型:
-布尔类型: bool。
- 整型: int8、 byte、 int16、 int、 uint、 uintptr等。
- 浮点类型: float32、 float64。
- 复数类型: complex64、 complex128。
- 字符串: string。
- 字符类型: rune。
- 错误类型: error。
此外, Go语言也支持以下这些复合类型:
-指针(pointer)
-数组(array)
- 切片(slice)
- 字典(map)
- 通道(chan)
- 结构体(struct)
- 接口(interface)
布尔类型
Go语言中的布尔类型与其他语言基本一致,关键字也为bool,可赋值为预定义的true和
false示例代码如下:
var v1 bool v1 = true v2 := (1 == 2) // v2也会被推导为bool类型
布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换
整型
类 型 长度(字节) 值 范 围
int8 1 128 ~ 127
uint8(即byte) 1 0 ~ 255
int16 2 -32 768 ~ 32 767
uint16 2 0 ~ 65 535
int32 4 -2 147 483 648 ~ 2 147 483 647
uint32 4 0 ~ 4 294 967 295
int64 8 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
uint64 8 0 ~ 18 446 744 073 709 551 615
int 平台相关 平台相关
uint 平台相关 平台相关
uintptr 同指针 在32位平台下为4字节, 64位平台下为8字节
两个不同类型的整型数不能直接比较,比如int8类型的数和int类型的数不能直接比较,但
各种类型的整型变量都可以直接与字面常量(literal)进行比较
var i int32 var j int64 i, j = 1, 2 if i == j { // 编译错误 fmt.Println("i and j are equal.") } if i == 1 || j == 2 { // 编译通过 fmt.Println("i and j are equal.")
浮点型
复数类型
对于一个复数z = complex(x, y),就可以通过Go语言内置函数real(z)获得该复数的实
部,也就是x,通过imag(z)获得该复数的虚部,也就是y。
字符串
var str string str = "Hello world" // 字符串赋值 ch := str[0] // 取字符串的第一个字符 fmt.Printf("The length of \"%s\" is %d \n", str, len(str)) fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)
字符串的内容可以用类似于数组下标的方式获取,但与数组不同,字符串的内容不能在初始化后被修改
数组
数组就是指一系列同一类型数据
的集合。数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数
组的长度。
[32]byte // 长度为32的数组,每个元素为一个字节 [2*N] struct { x, y int32 } // 复杂类型数组 [1000]*float64 // 指针数组 [3][5]int // 二维数组 [2][2][2]float64 // 等同于[2]([2]([2]float64))
在Go语言中,数组长度在定义后就不可更改,在声明时长度可以为一个常量或者一个常量
表达式(常量表达式是指在编译期即可计算结果的表达式)。数组的长度是该数组类型的一个内
置常量,可以用Go语言的内置函数len()来获取
数组可以通过下标访问,从0开始
数组可以通过 range遍历访问,range表达式有两个返回值,第一个是索引,
第二个是元素的值:
在Go语言中数组是一个值类型(value type)。所有的值类型变量在赋值
和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该
参数将发生数据复制。因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是所
传入数组的一个副本
数组切片
初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是
个指针。数组切片的数据结构可以抽象为以下3个变量:
- 一个指向原生数组的指针;
- 数组切片中的元素个数
- 数组切片已分配的存储空间
创建数组切片
创建数组切片的方法主要有两种——基于数组和直接创建
数组切片可以基于一个已存在的数组创建。数组切片可以只使用数组的一部分元素或者整个
数组来创建,甚至可以创建一个比所基于的数组还要大的数组切片
package main import "fmt" func main() { // 先定义一个数组 var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // 基于数组创建一个数组切片 var mySlice []int = myArray[:5] fmt.Println("Elements of myArray: ") for _, v := range myArray { fmt.Print(v, " ") } fmt.Println("\nElements of mySlice: ") for _, v := range mySlice { fmt.Print(v, " ") } fmt.Println() }
直接创建
并非一定要事先准备一个数组才能创建数组切片。 Go语言提供的内置函数make()可以用于
灵活地创建数组切片。
创建一个初始元素个数为5的数组切片,元素初始值为0:
mySlice1 := make([]int, 5)
创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
mySlice2 := make([]int, 5, 10)
直接创建并初始化包含5个元素的数组切片:
mySlice3 := []int{1, 2, 3, 4, 5}
与数组相比,数组切片多了一个存储能
力(capacity)的概念,即元素个数和分配的空间可以是两个不同的值
合理地设置存储能力的
值,可以大幅降低数组切片内部重新分配内存和搬送内存块的频率,从而大大提高程序性能
数组切片支持Go语言内置的cap()函数和len()函数,代码清单2-2简单示范了这两个内置
函数的用法。可以看出, cap()函数返回的是数组切片分配的空间大小,而len()函数返回的是
数组切片中当前所存储的元素个数。
package main import "fmt" func main() { mySlice := make([]int, 5, 10) fmt.Println("len(mySlice):", len(mySlice)) fmt.Println("cap(mySlice):", cap(mySlice)) } 该程序的输出结果为: len(mySlice): 5 cap(mySlice): 10
函数append()的第二个参数其实是一个不定参数,我们可以按自己需求添加若干个元素,
甚至直接将一个数组切片追加到另一个数组切片的末尾:
mySlice2 := []int{8, 9, 10}
// 给mySlice后面添加另一个数组切片
mySlice = append(mySlice, mySlice2...)
数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间
(即cap()调用返回的信息),数组切片会自动分配一块足够大的内存。
基于数组切片创建切片
oldSlice := []int{1, 2, 3, 4, 5}
newSlice := oldSlice[:3] // 基于oldSlice的前3个元素构建新数组切片
有意思的是,选择的oldSlicef元素范围甚至可以超过所包含的元素个数,比如newSlice
可以基于oldSlice的前6个元素创建,虽然oldSlice只包含5个元素。只要这个选择的范围不超
过oldSlice存储能力(即cap()返回的值),那么这个创建程序就是合法的。 newSlice中超出
oldSlice元素的部分都会填上0。
内容复制
数组切片支持Go语言的另一个内置函数copy(),用于将内容从一个数组切片复制到另一个
数组切片。如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行
复制。下面的示例展示了copy()函数的行为:
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置
map
声明
var myMap map[string] PersonInfo
其中, myMap是声明的map变量名, string是键的类型, PersonInfo则是其中所存放的值类型
创建
我们可以使用Go语言内置的函数make()来创建一个新map。下面的这个例子创建了一个键
类型为string、值类型为PersonInfo的map:
myMap = make(map[string] PersonInfo)
要从map中查找一个特定的键,可以通过下面的代码来实现:
value, ok := myMap["1234"]
if ok { // 找到了
// 处理找到的value
}