golang使用笔记
文章目录
本文主要记录golang使用的一些笔记。
安装
参考官网 安装说明 操作即可。
Linux
|
|
然后把 /usr/local/go/bin
加入到 PATH
,可以在 ~/.bash_profile
文件加入以下内容:
|
|
重新登录一下或者重启之后生效。
另外可以设置下国内代理和GO111MODULE
。
|
|
IDE
推荐使用 VSCode 或者 GoLand 。
测试代码片段使用 playground 也挺不错。
教程
可以参考以下教程,本文主要记录一些没讲到的或者需要注意的点。
另外可能需要科学上网才能访问。
扩展阅读
module
新版go已经支持module,可以通过 go mod
管理依赖。
具体参考官方说明 Using Go Modules。
项目内部的pkg可以通过项目名+子目录路径形式导入。
|
|
doc
通过 go doc
命令可以查看package相关文档。
比如说查看内置函数make的使用说明:
|
|
还可以安装godoc,支持离线模式查看文档(不用经常科学上网):
|
|
import
|
|
更详细的可以看 Import declarations 的说明。
导出规则
只有首字母大写的symbol
才会被导出,包括package的函数、变量以及各种协议的编解码等。
入口
package main的main函数为程序入口。
每个package的init函数会自动调用。
变量声明
函数内才可以使用 :=
自动推导声明,否则需要完整的声明。
不同类型需要显式转换。
array
array是静态数组。
|
|
变参
具体参考 这里 的说明。
|
|
闭包
支持闭包,即持有外层上下文(变量)引用的函数。
|
|
流程控制
if
可以有for类似的初始化表达式,定义的变量在if else代码块中有效。
多行条件,运算符要放在最后(如&&
)。
switch
分支默认break,如果不需要break,要么case写在一起,要么使用 fallthrough
关键字。
分支是表达式,不局限于数字。
defer
defer后进先出,参数会先求值。
defer在函数退出时调用,而不是离开代码块时,因此for循环应避免使用defer。
defer适合就地安排收尾工作,比如说释放资源(申请和释放配对、不容易遗漏处理)。
另外也可以通过defer统计函数调用耗时。
slice
slice类似数组的引用,不存实际数据。
slice可以当作动态数组来使用,通过make
创建。
|
|
注意append
不直接修改slice,而是返回新的slice,所以一般都要赋值回去。
另外使用range
遍历更好,不容易出现越界问题。
range遍历的元素是值拷贝,更新元素内容的话需要通过索引访问。
map
存储键值型数据,通过字面量或者make
创建、初始化后才能使用。
struct
当struct内匿名嵌入一个struct字段,能够拥有其所有变量和方法。
不管是具名嵌入还是匿名嵌入到struct,实质都是组合。
多态通过interface实现。
公有、私有控制通过symbol名称(变量名、函数名、字段名等)首字母的大小写实现。
接口与反射
参考 golang反射 的说明。
另外接口是可以组合的。
|
|
指针
指针调用方法或访问变量使用 .
运算符(而不是->
)。
没有指针算术运算操作,减少野指针。
并发
参考文档 Share Memory By Communicating 以及 代码示例 。还可以参考 stackoverflow 上面的解释。
Do not communicate by sharing memory; instead, share memory by communicating.
简单来说就是不要通过加锁共享内存的方式通信,而要通过通信让渡使用权(所有权)来共用内存。
goroutine
协程是golang有力的武器,使用简单、开销小。
需要并发或者有阻塞操作的地方都可以新开协程处理。
一般需要配合超时控制(context, time)和取消(channel),避免协程不能正常退出。
channel
make, new, &Struct{k:v}
make主要用于创建map, slice, chan。返回对应类型的对象,而不是指针。
|
|
new相当于malloc+赋零值(zero value),返回的是指针。
|
|
&Struct{k:v}用于初始化结构体。
make、new和&Struct{k:v}默认从栈上分配,但有可能逃逸到堆(比如说调用fmt.Println
)。
具体可以参考 Golang逃逸分析与优化 。
JSON
参考 JSON操作 的说明。
protobuf
参考 protobuf操作 的说明。
cgo
cgo申请的内存需要显式释放,因为gc不处理。
|
|
cgo尽量只调用编解码接口,不调用(外部库中)可能导致阻塞的收发包接口。
执行外部命令
参考 执行外部命令 的说明。
context
参考 context包 的说明。
交叉编译
1.5版本以后的Go交叉编译十分简单,设置GOOS
和GOARCH
变量即可:
|
|