Golang实践录:开篇

自去年开始,因工作的关系,需要使用 Golang 进行开发。一来是工作,二来多了解一个新语言,总归是有好处。现在虽然不是主攻 Golang,但可能用来写一些小工具。

本系列不会系统介绍Golang,只是根据笔者接触的某个点进行记录,可以认为是一个笔记集。

一、我对Golang的认识

Go生态好,模块多,当然,如NodeJS、Python亦多,但不同语言侧重点不同。如Java侧重后台开发,C偏重底层,Pyhthon则是数据分析,爬虫,Go在虚拟化运维方面,但是没有定法,使用哪种语言没有限制,只有方便不方便,快速不快速。

有部分包无法下载,需要使用花费一定时间解决。可以使用国内镜像源,使用github下载,等等。

虽然 Go 跨平台,但有些特性与系统相关,因为最好使用多个系统测试。如果明确只使用某系统,则无须如此。

笔者在Windows上安装,也在Ubuntu安装(使用vagrant),为了方便管理,两套系统均使用同一目录作为工程目录。

二、Golang 安装

Golang在Windows系统的安装

下载:,版本为1.13.4。包名为go1.13.4.windows-amd64.zip。解压到D盘(或其它盘)。

设置几个环境变量:

1
2
3
4
GOBIN D:\go\bin
GOROOT D:\go
PATH:%GOBIN%
GOPATH:E:\project\golang

GOPATH即为工程目录。

Golang在Linux系统的安装

直接在命令行下载、解压:

1
2
wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
tar zxf go1.13.4.linux-amd64.tar.gz -C /usr/local/

修改~/.bashrc,添加:

1
2
3
4
5
export GOROOT=/usr/local/go
export GOBIN=$GOROOT/bin
export PATH=$PATH:$GOBIN
export GOPATH=/vagrant/golang
export GOPROXY=https://goproxy.cn

注1:在Windows,使用Vagrant启动虚拟机,其工程目录实际为E:\project\,故GOPATH的/vagrant/golang目录,与E:\project\golang实际为同一目录,此情况下,同一套代码在两个系统可同时使用。
注2:设置了 GOBIN,当使用 go get 安装包时,会安装到此目录,否则会安装到 GOPATH 的 bin 目录。
注3:有些项目,会依赖于 golang 版本,一般会有文档说明。

三、环境问题

golang.org包

因为众所周知的原因,有部分包无法正常访问。需要额外花工夫解决出现的问题。

1
cannot find package "golang.org/x/sys/unix" in any of:

原因:golang.org无法访问
解决:github有镜像,可下载,重命名。在$GOPATH)/src目录下执行:

1
2
3
4
5
6
mkdir -p  golang.org/x
cd golang.org/x/
git clone https://github.com/golang/sys
其它类似的有:
git clone https://github.com/golang/crypto
git clone https://github.com/golang/text

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"

参考: 。

环境变量

GOROOT 和 GOPATH 不能相同,否则会提示:

1
$GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'

1
2
go env  # 查看go的环境变量
go env -w GO111MODULE=off # 设置环境变量

四、工程概述

GOPATH目录下创建三个目录:

  • src 存放源代码,每个工程一个单独的目录
  • pkg 编译过后生成的包文件存放目录
  • bin 编译后生产的可执行文件和go相关的工具

五、go简单使用

1
2
3
4
5
6
7
go build
go build foo.go
go run main.go
go get -u github.com/xxx/yyy
查看环境: go env

查看包:go doc xxx

go install 会安装到GOBIN目录,一般项目可不用如此操作。

六、编码小结

右大括号{在行尾,如在新一行,编译不通过。
一般使用小写+大写方式。
函数:大写 导出,小写 包内(跨文件)可见。
变量:大写导出,小写包内可见。专用名称,可大写或小写。
接口、结构体:大写(一说小+大)。
文件名、包名:小写。

要慢慢熟悉的:大括号位置、if/for/没有小括号。
如果引入的包不使用,又不想删除(后面可能会用到),可以注释掉,也可以调用这些包的函数,放到函数中,但不调用这个函数。
格式要求严格,如a为uint16, b为[]bytea = b[0]出错,需要转换a = uint16(b[0])。另外,a = -1也出错,因为是无符号的。
可用 go fmt 格式化代码。

基本知识:
打印:

1
2
fmt.Printfln("Hello world");
fmt.Printf("Hello %v\n", "world");

代码片段(用以切换语言时看):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

有传入、付出参数
func sqrt(x float64) float64 {
ret := 1.0
for i := 0; i < 10; i++ {
ret = ret - (ret*ret - x) / 2 / ret
}

return ret
}

"类"
package class

import (
true"fmt"
)

// 空结构体
type SimpleClass struct {
// nothing
}

// "类"的形式
func (p *SimpleClass) printf() {
truefmt.Printf("%v\n", "hello world");
}

// 大写,包外可见
func SimpleTest() {

c := SimpleClass{};
c.printf();
}

主函数文件:
package main

import (
"class"
)
func main() {
class.SimpleTest();
}
}

七、小实验

自实现模块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 周三

  • 本文作者:李迟
  • 版权声明:原创文章,版权归署名作者,转载建议注明出处(当然不注明亦可)。
  • 本文链接:/golang/golang-start.html