基础类型主要有整型、浮点数、复数、布尔型、字符串。与其他语言比较类似,这里不一一赘述。 复合类型有数组([N]T)、切片([]T)、字典(map)、结构体(struct)、通道(chan)、指针(*T)。

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

var a [3]int //声明一个长度为3的整型数组
var q [3]int = [3]int{1, 2, 3} //数组的声明并初始化
q := [...]int{1, 2, 3} //另一种写法

切片(slice)代表变长的序列,序列中每个元素都有相同的类型,由三个部分构成:指针、长度和容量。slice就像一个没有固定长度的数组,它提供了访问数组子序列(或者全部)元素的功能,底层引用一个数组对象。它的零值等于nil。

var s []int    // len(s) == 0, s == nil
s = []int{}    // len(s) == 0, s != nil

要判断一个slice是否是空的,使用len(s) == 0来判断,而不应该用s == nil来判断。用内置的append函数向slice追加元素。

map是一个无序的key/value对的集合,可以写为map[K]V,K和V分别对应key和value,所有的key都有相同的类型,所有的value也有着相同的类型,key和value可以是不同的类型。key必须是支持==比较的数据类型,通过key是否相等来判断是否已经存在。不要用浮点数用做key的类型,可能出现的NaN和任何浮点数都不相等。内置的make函数可以创建一个map,内置的delete函数可以删除元素。注意其遍历的顺序是随机的,即每一次遍历的顺序都不相同。

m := make(map[string]int)

或直接声明并初始化

ages := map[string]int{
    "Tom": 30,
    "Jim": 40,
  }

判断是否存在某个Key

if age, ok := ages["Tom"]; ok {
    fmt.Println("已存在")
  } else {
   fmt.Println("不存在")
   }

结构体是一种聚合的数据类型,是由零个或多个任意类型的值组合而成,每个值称为结构体的成员。

type Point struct {
    X, Y int
  }
  type Circle struct {
    Center Point
    Radius int
  }

通道(chan)是go最核心的特色之一,一个channel有发送和接受两个主要操作。发送和接收两个操作都是用<-运算符。在发送语句中,<-运算符分割channel和要发送的值。在接收语句中,<-运算符写在channel对象之前。一定要初始化后才能进行读写操作,否则会永久阻塞。关于通道,后面我还会详细介绍,它和goroutine息息相关。

ch = make(chan int)    //无缓冲通道
ch = make(chan int,5) //有缓冲通道