go get:获取远程包(需提前安装git或hg)
go run:直接运行程序go build:测试编译,检查是否有编译错误go fmt:格式化源码go install:编译包文件并编译整个程序go test:运行测试文件go doc:查看文档go程序的一般结构:
go程序是通过package来组织的 只有package名称为main的包可以包含main函数 一个可执行程序有且仅有一个main包通过import关键字来导入其他非main包
通过const关键字来进行常量的定义 通过在函数体外部使用var关键字来进行全局变量的声明与福祉 通过type关键字来进行结构(struct)或接口(interface)的声明 通过func关键字来进行函数的声明 go语言中,使用大小写来决定该常量,变量,类型,接口,结构或函数,是否可以被外部包所调用 根据约定:函数名首字母小写为private,函数名首字母大写为public单个变量的声明与赋值:
变量的声明格式:var <变量名称> <变量类型> 变量的赋值格式:<变量名称> = <表达式> 声明的同时赋值:var <变量名称> [变量类型] = <表达式>多个变量的声明与赋值:
全局变量的声明可使用var()的方式进行简写 全局变量的声明不可以省略var,但可使用并行方式 所有变量都可以使用类型推断 局部变量不可以使用var()的方式简写,只能使用并行方式常量的定义
常量的值在编译时就已经确定 常量的定义格式与变量基本相同 等号右侧必须是常量或者常量表达式 常量表达式中的函数必须是内置函数判断语句if
条件表达式没有括号 支持一个初始化表达式(可以是并行方式) 左大括号必须和条件语句或else在同一行 支持单行模式 初始化语句中的变量为block级别,同时隐藏外部同名变量循环语句for:
go只有for一个循环语句关键字,但支持3种形式 初始化和步进表达式可以是多个值 条件语句每次循环都会被重新检查,因此不建议在条件语句中使用函数,尽量提前计算好条件并以变量或常量代替 左大括号必须和条件语句在同一行选择语句switch:
可以使用任何类型或表达式作为条件语句 不需要写break,一旦条件符合自动终止 如希望继续执行下一个case,需使用fallthrough语句 支持一个初始化表达式(可以是并行方式),右侧需跟分号 左大括号必须和条件语句在同一行数组array:
定义数组的格式:var <varName> [n]<type> , n>=0 数组长度也是类型的一部分,因此具有不同长度的数据为不同类型 注意区分指向数组的指针和指针数组 数组在go中为值类型 数组之间可以使用==或!=进行比较,但不可以使用<或> 可以使用new来创建数组,此方法返回一个指向数组的指针 go支持多维数组切片slice:
其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生产 使用len()获取元素个数,cap获取容量 一般使用make()创建 如果多个slice指向相同底层数组,其中一个的值改变会影响全部make([]T,len,cap)
其中cap可以省略,则和len的值相同 len表示存数的元素个数,cap表示容量reslice:
reslice时索引以被slice的切片为准 索引不可以超过被slice的切片的容量cap()值 索引越界不会导致底层数组的重新分配而是引发错误append:
可以在slice尾部追加元素 可以将一个slice追加在另一个slice尾部 如果最终长度未超过追加到slice的容量则返回原始slice 如果超过追加到的slice的容量则将重新分配数组并拷贝原始数据map:
类似其他语言中的哈希表或者字典,以key-value形式存储数据 key必须是支持==或!=比较运算的类型,不可以是函数,map或slice map查找比线性搜索快得多,但比使用索引访问数据的类型慢100倍 map使用make()创建,支持:=这种简写方式make([keyType]valueType,cap),cap表示容量,可省略
超出容量时会自动扩充,但尽量提供一个合理的初始值 使用len()获取元素个数键值对不存在时自动添加,使用delete()删除某键值对
使用for range对map和slice进行迭代操作函数function:
go函数不支持嵌套,重载和默认参数 支持以下特性: 无需声明原型,不定长度变参,多返回值,命名返回值参数,匿名函数,闭包定义函数关键字func,且大括号不能另起一行
函数也可以作为一种类型使用defer:
执行方式类似其他语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行 及时函数发生严重错误也会执行 支持匿名函数的调用 常用于资源清理,文件关闭,解锁,以及记录时间等操作 通过与匿名函数配合可在return之后修改函数计算结果 如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即以及获得了拷贝,否则则是引用某个变量的地址go没有异常机制,但有panic/recover模式来处理错误
panic可以在任何地方引发,但recover只有在defer调用的函数中有效结构struct:
go中的struct与C中的struct非常相似,并且go没有class 使用type <name> struct{}定义结构,名称遵循可见性规则 支持指向自身的指针类型成员 支持匿名结构,可用做成员或定义成员变量 匿名结构也可用用于map值 可用使用字面值对结构进行初始化 允许直接通过指针来读写结构成员 相同类型的成员可进行直接拷贝赋值 支持==与!=比较运算符,但不支持<或> 支持匿名字段,本质上是定义了以某个类型名为名称的字段 嵌入结构作为匿名字段看起来像继承,但不是继承 可以使用匿名字段指针方法method:
go中虽没有class,但依旧有method 通过显示说明receiver来实现与某个类型的组合 只能为同一个包中的类型定义方法 receiver可以是类型的值或者指针 不存在方法重载 可以使用值或指针来调用方法,编译器会自动完成转换 从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接受的第1个参数 如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法 类型别名不会拥有底层类型所附带的方法 方法可以调用结构中的非公开字段接口interface
接口是一个或多个方法签名的集合 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这成为structural typing 接口只有方法声明,没有实现,没有数据字段 接口可以匿名嵌入其他接口,或嵌入到结构中 将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针 只有当接口存储的类型和对象都为nil时,接口才等于nil 接口调用不会做receiver的自动转换 接口同样支持匿名字段方法 接口也可以实现类似OPP中的多态 空接口可以作为任何类型数据的容器