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
支持整形类型如下:
注意:int和int32在Go语言里被认为是两种不同的类型,编译器也不会帮你自动做类型转换,必须使用强制类型转换进行转换
go 语言的所有的运算和C语言相同,除了取反符号,c语言取反是 ~, 而go 是^
Go语言定义了两个类型float32和float64,其中float32等价于C语言的float类型,float64等价于C语言的double类型
浮点型比较:
因为浮点数不是一种精确的表达方式,所以像整型那样直接用==来判断两个浮点数是否相等是不可行的,这可能会导致不稳定的结果。
下面是一种推荐的替代方案:
import "math"
// p为用户自定义的比较精度,比如0.00001
func IsEqual(f1, f2, p float64) bool {
return math.Fdim(f1, f2) < p
}
表示法:
var value1 complex64
或者:
value3 := complex(3.2, 12)
声明:
var str string
Go语言内置的函数len()来取字符串的长度
在Go语言中支持两个字符类型,一个是byte(实际上是uint8的别名),代表UTF-8字符串的单个字节的值;另一个是rune,代表单个Unicode字符
以下为常见的数组声明方法:
元素访问
可以使用数组下标来访问数组中的元素。与C语言相同,数组下标从0开始, len(array)-1
则表示最后一个元素的下标
Go语言还提供了一个关键字range,用于便捷地遍历容器中的元素
例如:
for i, v := range array {
fmt.Println("Array element[", i, "]=", v)
}
数组的长度在定义之后无法再次修改;数组是值类型,每次传递都将产生一份副本。显然这种数据结构无法完全满足开发者的真实需求。不用失望, Go语言提供了数组切片( slice)这个非常酷的功能来弥补数组的不足。初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针。数组切片的数据结构可以抽象为以下3个变量:
a:一个指向原生数组的指针
b:数组切片中的元素个数;
c:数组切片已分配的存储空间。
从底层实现的角度来看,数组切片实际上仍然使用数组来管理元素,因此它们之间的关系让C++程序员们很容易联想起STL中std::vector和数组的关系。基于数组,数组切片添加了一系列管理功能,可以随时动态扩充存放空间,并且可以被随意传递而不会导致所管理的元素被重复复制。
创建数组切片:
有两种方式,基于数组和直接创建
基于数组:
注意: 基于数组创建的数组切片,数组切片和数组使用的是同一空间,则修改数组,同时也修改了切片
参考slice.go
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)的概念,即元素个数和分配的空间可以是两个不同的值。
假如你明确知道当前创建的数组切片最多可能需要存储的元素个数为50,那么如果你设置的存储能力小于50,比如20,那么在元素超过20时,底层将会发生至少一次这样的动作——重新分配一块“够大”的内存,并且需要把内容从原来的内存块复制到新分配的内存块,这会产生比较明显的开销。给“够大”这两个字加上引号的原因是系统并不知道多大才是够大,所以只是一个简单的猜测。比如,将原有的内存空间扩大两倍,但两倍并不一定够,所以之前提到的内存重新分配和内容复制的过程很有可能发生多次,从而明显降低系统的整体性能。但如果你知道最大是50并且一开始就设置存储能力为50,那么之后就不会发生这样非常耗费CPU的动作,从而达到空间换时间的效果。
数组切片支持Go语言内置的cap()函数和len()函数,cap()函数返回的是数组切片分配的空间大小,而len()函数返回的是数组切片中当前所存储的元素个数
参考代码:slice2.go
package main
import "fmt"
func main() {
mySlice := make([]int, 5, 10)
fmt.Println("len(mySlice):", len(mySlice))
fmt.Println("cap(mySlice):", cap(mySlice))
}
基于数组切片创建数组切片:
类似于数组切片可以基于一个数组创建,数组切片也可以基于另一个数组切片创建,且创建方式与基于数组相同
内容复制:
数组切片支持Go语言的另一个内置函数copy(),用于将内容从一个数组切片复制到另一个数组切片。如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行复制。
参考代码 map1.go
package main
import "fmt"
// PersonInfo是一个包含个人详细信息的类型
type PersonInfo struct {
ID string
Name string
Address string
}
func main() {
var personDB map[string] PersonInfo
personDB = make(map[string] PersonInfo)
// 往这个map里插入几条数据
personDB["12345"] = PersonInfo{"12345", "Tom", "Room 203,..."}
personDB["1"] = PersonInfo{"1", "Jack", "Room 101,..."}
// 从这个map查找键为"1234"的信息
person, ok := personDB["1234"]
// ok是一个返回的bool型,返回true表示找到了对应的数据
if ok {
fmt.Println("Found person", person.Name, "with ID 1234.")
} else {
fmt.Println("Did not find person with ID 1234.")
}
}
参考如上代码:
声明:
var personDB map[string] PersonInfo
创建:
personDB = make(map[string] PersonInfo)
也可以选择是否在创建时指定该map的初始存储能力,下面的例子创建了一个初始存储能力为100的map:
myMap = make(map[string] PersonInfo, 100)
也可以直接初始化:
myMap = map[string] PersonInfo{
"1234": PersonInfo{"1", "Jack", "Room 101,..."},
}
操作
插入: personDB["12345"] = PersonInfo{"12345", "Tom", "Room 203,..."}
删除:delete(myMap, "12345")
如果“12345”这个键不存在,那么这个调用将什么都不发生,也不会有什么副作用。但是如果传入的map变量的值是nil,该调用将导致程序抛出异常( panic)。