语言特色
简洁、快速、安全
并行、有趣、开源
内存管理、数据安全、编译迅速
关键字和标识符 关键字 关键字是一些特殊的用来帮助编译器理解和解析源代码的单词。
1 2 3 4 5 break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
标识符 一个标识符是一个以Unicode字母或者_开头并且完全由Unicode字母和Unicode数字组成的单词。
基本类型、变量和常量 基本内置类型 Go 支持内置基本类型(预声明类型)有:
通常,int 、uint 和 uintptr 的尺寸依赖于具体的编译器实现。
变量 Go 中声明变量一般使用 var 关键字。
声明变量时,如果指定了变量类型但没有初始化,则变量的默认值为指定类型的零值:
1 2 3 4 5 6 var numericalVal int println (numericalVal) var stringVal string println (stringVal) var booleanVal bool println (booleanVal)
如果没有指定变量类型,但进行了初始化,Go 会自动推断变量的类型:
1 2 var valF, valS, valT = "" , 100 , 100.10 fmt.Printf("valF = %T, valS = %T, valT = %T \n" , valF, valS, valT)
还可以使用 := 来声明变量,只能用在函数体重:
1 2 valF := "Anthor var" fmt.Printf("valF value = %v and type = %T" , valF, valF)
声明全局变量:
1 2 3 4 5 var ( valI int valB bool valS string )
如果不需要某个值,可以使用 _ 将其抛弃:
1 2 var valA, valB = 1 , 2 _, valB = 3 , 4
常量 常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
1 2 const valBoolean, valInt, valFloat, valString = false , 10 , 3.14 , "string" fmt.Printf("%v %v %v %v" , valBoolean, valInt, valFloat, valString)
特殊常量值 itoa :
1 2 3 4 5 6 const ( a = iota b c ) fmt.Printf("%v %v %v \n" , a, b, c)
函数 Go 中使用 func 关键字来声明一个函数
1 func funcName ([params list]) [return types ] {}
数组 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。
数组的一般声明方式:
1 var arrayName [arraySize] elementType
初始化数组:
1 2 3 4 5 6 7 8 var intArray = [3 ]int {1 , 2 , 3 }fmt.Printf("%T %v \n" , intArray, intArray) stringArray := [3 ]string {"a" , "b" , "c" } fmt.Printf("%T %v \n" , stringArray, stringArray) booleanArray := [...]bool {true , false } fmt.Printf("%T %v \n" , booleanArray, booleanArray)
指针 一个指针变量指向了一个值的内存地址。
指针的使用类似于变量和常量,在使用指针之前需要声明它:
1 var pointerName *pointerType
举几个例子:
1 2 var intPointer *int var stringPointer *bool
简单使用:
1 2 3 4 var intPointer *int var intVal = 99 intPointer = &intVal fmt.Printf("%v %v %v" , intPointer, &intPointer, *intPointer)
一个指针变量声明后如果没有被赋值,它的值为 nil ,称为空指针。
结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
定义结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package mainimport "fmt" type student struct { name string age int height float32 weight float32 } func main () { var studentA = student{"Mike" , 18 , 178 , 78.9 } fmt.Printf("%v %T \n" , studentA, studentA) fmt.Printf("name = %v \n" , studentA.name) fmt.Printf("age = %v \n" , studentA.age) var studentAPointer = &studentA fmt.Printf("%v %T \n" , studentAPointer, studentAPointer) fmt.Printf("name = %v \n" , studentAPointer.name) fmt.Printf("age = %v \n" , studentAPointer.age) }
切片 Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
定义切片:
1 2 3 4 5 6 7 8 9 10 11 var numberSlice []int numberSlice = make ([]int , 3 ) fmt.Printf(" %v %T \n" , numberSlice, numberSlice) stringSlice := []string {"a" , "b" , "c" } fmt.Printf("%v %T \n" , stringSlice, stringSlice) floatArray := [...]float32 {1.1 , 2.2 , 3.3 } floatSlice := floatArray[0 :2 ] fmt.Printf("%v %T \n" , floatSlice, floatSlice) [1.1 , 2.2 ] []float32
切片的操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 intSlice := []int {1 , 2 , 3 , 4 , 5 , 6 } fmt.Printf("slice length = %v \n" , len (intSlice)) fmt.Printf("slice capacity = %v \n" , cap (intSlice)) fmt.Printf("slice [3] = %v \n" , intSlice[3 ]) fmt.Printf("slice [0:1] = %v \n" , intSlice[0 :1 ]) fmt.Printf("slice [0:2] = %v \n" , intSlice[0 :2 ]) fmt.Printf("slice [:3] = %v \n" , intSlice[:3 ]) fmt.Printf("slice [3:] = %v \n" , intSlice[3 :]) intSlice = append (intSlice, 7 ) fmt.Printf("slice = %v \n" , intSlice) intSlice = append (intSlice, 8 , 9 , 10 ) fmt.Printf("slice = %v \n" , intSlice) anotherSlice := []int {11 , 12 , 13 } intSlice = append (intSlice, anotherSlice...) fmt.Printf("slice = %v \n" , intSlice) thirdSlice := []int {88 , 99 } copy (intSlice, thirdSlice) fmt.Printf("slice = %v \n" , intSlice)
范围 Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 intSlice := []int {1 , 3 } for index, num := range intSlice { fmt.Printf("index = %v num = %v \n" , index, num) } stringMap := map [string ]string {"a" : "A" , "b" : "B" } for key, val := range stringMap { fmt.Printf(" key = %v val = %v \n" , key, val) }
集合 Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
定义 Map:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var numMap map [string ]int numMap = make (map [string ]int ) numMap["a" ] = 1 fmt.Printf("map = %v \n" , numMap) stringMap := make (map [string ]string ) stringMap["name" ] = "Mike" stringMap["age" ] = "十八" for key, val := range stringMap { fmt.Printf("key = %v value = %v \n" , key, val) } delete (stringMap, "age" )fmt.Printf("map = %v \n" , stringMap)