自去年开始,因工作的关系,需要使用 Golang 进行开发。一来是工作,二来多了解一个新语言,总归是有好处。现在虽然不是主攻 Golang,但可能用来写一些小工具。
本系列不会系统介绍Golang,只是根据笔者接触的某个点进行记录,可以认为是一个笔记集。
一、我对Golang的认识
Go生态好,模块多,当然,如NodeJS、Python亦多,但不同语言侧重点不同。如Java侧重后台开发,C偏重底层,Pyhthon则是数据分析,爬虫,Go在虚拟化运维方面,但是没有定法,使用哪种语言没有限制,只有方便不方便,快速不快速。
有部分包无法下载,需要使用花费一定时间解决。可以使用国内镜像源,使用github下载,等等。
虽然 Go 跨平台,但有些特性与系统相关,因为最好使用多个系统测试。如果明确只使用某系统,则无须如此。
Go 统一了编码风格,起初还不习惯,但久了发现从语言层级来强制风格也有好处,至少能避免一些低级错误发生。
Go 有很多地方属于原创,如 defer,可以在函数返回前做一些注销、关闭等操作(如关闭文件)。
笔者在Windows上安装,也在Ubuntu安装(使用vagrant),为了方便管理,两套系统均使用同一目录作为工程目录。
二、Golang 安装
Golang在Windows系统的安装
下载:https://studygolang.com/dl ,版本为1.13.4。包名为go1.13.4.windows-amd64.zip
。解压到D盘(或其它盘)。
设置几个环境变量:
1 | GOBIN D:\go\bin |
GOPATH即为工程目录。
Golang在Linux系统的安装
直接在命令行下载、解压:
1 | wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz |
修改~/.bashrc,添加:
1 | export GOROOT=/usr/local/go |
注1:在Windows,使用Vagrant启动虚拟机,其工程目录实际为E:\project\,故GOPATH的/vagrant/golang目录,与E:\project\golang实际为同一目录,此情况下,同一套代码在两个系统可同时使用。 补充:经一段时间测试使用,发现个别库还是有不同,Linux 和 Windows 使用同一套库(的目录),会出现莫名的问题,因此,不同的系统,GOPATH 设置了不同的目录。
注2:设置了 GOBIN,当使用 go get 安装包时,会安装到此目录,否则会安装到 GOPATH 的 bin 目录。
注3:上面也设置了 MYGO 环境变量,方便快速定位到个人目录。
注4:有些项目,会依赖于 golang 版本,一般会有文档说明。
三、环境问题
golang.org包
因为众所周知的原因,有部分包无法正常访问。需要额外花工夫解决出现的问题。
1 | cannot find package "golang.org/x/sys/unix" in any of: |
原因:golang.org无法访问
解决:github有镜像,可下载,重命名。在$GOPATH)/src目录下执行:
1 | mkdir -p golang.org/x |
1 | cannot find package "github.com/go-playground/validator/v10" |
go版本太低(1.6),升级为1.13解决。(注:v10的确不存在,但代码的确引用该包)
代理
1.13 及以上使用:
1 | go env -w GOPROXY=https://goproxy.cn,direct |
也可以设置环境变量:
1 | $ echo "export GOPROXY=https://goproxy.cn" >> ~/.bashrc && source ~/.bashrc |
默认代理:GOPROXY="https://proxy.golang.org,direct"
。
参考: https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md 。
环境变量
GOROOT 和 GOPATH 不能相同,否则会提示:
1 | $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath' |
1 | go env # 查看go的环境变量 |
四、工程概述
GOPATH目录下创建三个目录:
- src 存放源代码,每个工程一个单独的目录
- pkg 编译过后生成的包文件存放目录
- bin 编译后生产的可执行文件和go相关的工具
2021.6记:用go get
下载github.com的包,位于目录pkg\mod\github.com
。临时缓存位于目录pkg\mod\cache\download\github.com
。
五、go简单使用
1 | go build |
注:go get 会自动下载编译安装包(如果包需要编译的话),也可以只下载不编译go get -d <xxx>
,再单独编译go build -x <xxx>
。加 -x 可输出详细的编译信息。
go install 会安装到GOBIN目录,一般项目可不用如此操作。
六、编码小结
右大括号{
在行尾,如在新一行,编译不通过。
一般使用小写+大写方式。
函数:大写 导出,小写 包内(跨文件)可见。
变量:大写导出,小写包内可见。专用名称,可大写或小写。
接口、结构体:大写(一说小+大)。
文件名、包名:小写。
要慢慢熟悉的:大括号位置、if/for/没有小括号。
如果引入的包不使用,又不想删除(后面可能会用到),可以注释掉,也可以调用这些包的函数,放到函数中,但不调用这个函数。
格式要求严格,如a为uint16, b为[]byte
,a = b[0]
出错,需要转换a = uint16(b[0])
。另外,a = -1
也出错,因为是无符号的。
可用 go fmt 格式化代码。
基本知识:
打印:
1 | fmt.Printfln("Hello world"); |
代码片段(用以切换语言时看):
1 |
|
七、小实验
自实现模块A,存入github.com,A使用到第三方库,go get
获取A会自动检测第三方库,如无则自动下载。
八、常见错误
1 | main.go:8:5: found packages a (a.go) and main (a1.go) in e:\project\golang\src\hello\a |
原因:同一个目录下,有2个包名。
解决:只保留一个包名,如必须有2个,则移到另一目录。
下载第三方依赖包时,其依赖的包可能存在于本地,但版本过旧,会出错。此时重新更新所有的依赖包即可。
PS:工作中切换语言时,先看几眼本文件,以便于思维的切换。
李迟 2020.08.19 周三