Introduction
Golang 只有25个关键词:
1 | break default func interface select |
Hello, Go
1 | packgae main |
- Go 是通过
package俩组织的,每个 Go 文件以package <pkgName开头,除了main包外,其余所有包都会被编译成*.a文件($GOPATH/pkg/$GOOS_$GOARCH),main包会被编译成可执行文件,并且其中的main函数被入口函数。 - Go是天生支持UTF-8的
Go基础
变量
var:=_- 已声明,但是未使用的变量会在编译时报错
1 | # 基本格式 |
常量
常量是在编译阶段就确定的值,且无法再运行时改变
1 | const constantName type |
- Go 常量和一般程序语言不同的是,可以指定相当多的小数位数(例如200位), 若指定給float32自动缩短为32bit,指定给float64自动缩短为64bit
内置基础类型
- bool,默认值为
false - 数值类型
- uint, int:长度相同,具体长度由不同编译器实现决定
rune,int8,int16,int32,int64byte,uint8,uint16,uint32,uint64rune是int32的别称,byte是uint8的别称- 不同类型直接不能相互赋值
float32和float64,没有float类型,默认为float64complex128和complex64复数(默认为complex128),如var c =1+2i
- 字符串
string- 使用一对双引号或者反引号括起来定义,反引号可以用来声明多行字符串,即 Raw 字符串
- Golang 字符串是不可变的,可以先将其转换成
[]byte来修改 +运算符可以拼接字符串
- 错误类型
error- Go 中
errors包可以用来处理错误信息
Go 数据底层存储

Some tricks
分组声明:
1 | import ( |
iota:
实现枚举,默认开始值为0,const 中每增加一行则加一。
1 | const ( |
一些约定
- 大写字母的变量和函数时可导出的,在其他包中可读取的,小写变量则是指在包中可访问
array, slice, map
array
1 | # array 声明格式 |
slice
slice 通常可以当成动态数组使用,但其实是一个引用类型,数据本质上还是存储在,slice 总是指向一个底层的 array。
由于 slice 是引用类型,所以对 slice 中的元素进行修改的话,底层的 array 中是能感知到的。
slice 可以理解成一个结构体,其包含了三个元素:
pointer:指向slice开始位置的指针len:slice 的长度cap:slice 开始位置到数组最后位置的长度

1 | # slice |
slice 由几个常用的内置函数:
len:获取 slice 长度cap:slice 的最大容量append:想 slice 追加一个或者多个元素,返回一个与 slice 相同类型的 slice- append 会影响到 slice 所引用的数组内容(即没扩容时,其他 slice 会看到变化的内容)
- 当底层数组无法容纳更多元素时,会发生扩容,新创建一个 array 保存元素,即
copy:拷贝 slice 到另一个 slice,并且返回复制的元素的个数
1 | a = arr[2:5] |
map
- map 是无序的
- map 长度不固定,也是一个引用类型
- len 函数返回 map 的Key的个数
- map 不是 thread-safe
- 使用
delte删除 map 的元素
1 | var numbers string[int] // 这是只是声明了一个引用类型,并没有指向任何空间,即为 nil |
make & new
make用于内建类型的内存分配(slice, map, channel),返回一个有初始值的 T 类型new用于各种类型的内存分配,其分配一个零值填充的 T 类型的内存空间,并返回其指针/地址,即一个*T
流程和函数
流程控制
if
1 | if i == 3 { |
goto
1 | // 标签名大小写敏感 |
for
1 | sum := 0 |
switch
1 | i := 10 |
函数
1 | func funcName(input1 type2, input2 type2) (output1 type1, output2 type2) { |
- 使用
func声明一个函数 - 函数可以有多个参数,可以返回多个值
- 返回值可以只写类型名,不谢返回值名称
- 如果有返回值名称,可以不显式的写 return 要返回的值,
- 如果只有一个返回值且不写返回值名称时,可以忽略返回值的括号
- 如果有返回值,必须 return
- 支持变长参数(使用 slice 实现)
- 参数是传值的,所以需要相当于传入的参数是原本值的一个copy,如果需要修改的话,则需要传入一个指针
- Go语言中channel,slice,map这三种类型的实现机制类似指针,所以可以直接传递,而不用取地址后传递指针。
defer可以让函数在执行到最后时,执行defer函数(按照逆序执行)- 函数可以作为值、类型:
type typeName func(input1 inputType1, input2 inputType2) (result resultType1)
1 | func Max(a, b int) int { |
Go 没有异常机制,但可以使用Panic and Recover:
Panic:中断原有的控制流程,并进入 panic 状态,函数 F 调用 panic,F 的 defer 函数会执行,并返回到 F 的调用位置,此时调用位置也像是掉用了 panic 一样,继续中断,一直返回向上,直到 panic 的 goroutine 所有调用函数返回Recover:让进入 panic 状态的 goroutine 恢复过来,recover函数只在 defer 中有效,如果在正常执行流程中调用 recover,则会无事发生。
1 | func f() { |
两个特殊的函数:
main函数:- 只在
package main中 - 没有返回值和参数
- 只在
init函数- 导包时被执行
- 可以定义多个
init函数,但是建议只写一个

使用import关键字来导包:
- 相对路径:
import "../model" - 绝对路径:
import "hello/world" - 使用
.将包中所有变量函数导入:import . "fmt" - 别名:
import f "fmt" _忽略包不导入,但执行init函数:import _ "fmt"