Go语言之安装环境及编程规范、代码格式化

前言

Go语言在多核并发上拥有原生的设计优势,Go语言从底层原生支持并发,无须第三方库、开发者的编程技巧和开发经验。

go是非常年轻的一门语言,它的主要目标是“兼具Python 等动态语言的开发速度和C/C++等编译型语言的性能与安全性”

Go最不方便的在于早期版本没有泛型,但是从1.18起也加入了泛型。

go适合做什么

  • 服务端开发
  • 分布式系统,微服务
  • 网络编程
  • 区块链开发
  • 内存KV数据库,例如boltDB、levelDB
  • 云平台

推荐文档:http://www.topgoer.com/

安装GO环境

下载安装

下载地址:https://studygolang.com/dl

推荐安装:

go1.18.7.windows-amd64.msi

go1.21.13.windows-amd64.msi

因为从1.18起才支持的泛型。

安装后查看

1
go version

成功显示

go version go1.18.7 windows/amd64

代理设置

设置环境变量GOPROXY=https://goproxy.cn

image-20210412110225584

测试

1
echo %GOPROXY%

GOPATH设置

默认安装后环境变量中会有GOPATH,如果没有添加上即可

设置环境变量GOPATH=%USERPROFILE%\go

如果没有对应文件夹,创建即可

1
mkdir %USERPROFILE%\go

IDEA配置

Go语言插件

Go语言支持插件

Plugins中直接搜索Go安装即可。

Go Plugin for IntelliJ IDEA

IDEA中格式化

新版本IDEA已经自带Actions on Save,可以忽略下面的设置。

安装 File Watchers 插件和Save Actions插件

image-20221006152001041

设置 Tools=>File Watchers 点击添加
image-20221006152735189

弹出的窗口按下图配置

image-20221006160513108

其中

Program 选择go安装目录下的gofmt

Argnuments 输入 -w $FilePath$

取消自动保存,否则会一更改就触发格式化。

注意

页面修改保存时才会格式化,如果没有格式化,重启IDEA即可。

要在保存的时候触发格式化

image-20221006160625585

安装依赖

在 Go 项目中,当存在 go.mod 文件时,安装依赖的方式非常直接,主要通过 go mod 相关命令来管理。以下是常用的操作步骤:

安装所有依赖

如果 go.mod 中已经列出了依赖(如 require 部分),直接执行以下命令即可下载并安装所有依赖到本地(默认存放在 $GOPATH/pkg/mod 目录):

1
go mod download

如果IDEA中还是找不到依赖,勾选这个配置

image-20251028122614958

添加依赖

添加新的依赖并自动更新 go.mod

如果需要引入新的依赖(例如某个第三方库),可以直接在代码中导入该库,然后执行:

1
go mod tidy

该命令会自动分析代码中实际使用的依赖,添加缺失的依赖到 go.mod,并移除未使用的依赖,同时下载新依赖到本地。

手动指定版本安装依赖

如果需要手动指定某个依赖的版本,可以使用 go get 命令,例如安装 github.com/gin-gonic/gin 的最新版本:

1
go get github.com/gin-gonic/gin

如果需要指定具体版本:

1
go get github.com/gin-gonic/gin@v1.9.1  # 安装 v1.9.1 版本

执行后,go.mod 会自动更新该依赖的版本信息,同时下载对应版本的依赖。

验证依赖是否安装成功

可以通过以下命令查看已安装的依赖列表:

1
go list -m all  # 列出项目所有依赖及其版本

总结:最常用的是 go mod download(安装已有依赖)和 go mod tidy(同步代码与依赖),根据需求选择即可。

构建脚本

build_linux64.bat

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
@echo off  
set TARGET_FILE=xh-control-ws
set TARGET_DIR=_dist
set TARGET_DIR_PATH=%cd%\%TARGET_DIR%\

echo ---------------------------------
echo Delete Origin Dir
IF EXIST %TARGET_DIR_PATH% rd /S /Q %TARGET_DIR_PATH%
IF NOT EXIST %TARGET_DIR% mkdir %TARGET_DIR%

echo ---------------------------------
echo Build API
set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0
go build

echo Copy API
move %TARGET_FILE% %TARGET_DIR_PATH% > NUL
xcopy /e /i "config" %TARGET_DIR_PATH%config > NUL

echo ---------------------------------
echo Success

pause

注册为服务

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/bin/bash
# chkconfig: 2345 85 15
# description:auto_run

APP_NAME=xh-control-ws
ROOT_DIR=/data/wwwjarapi/8931mcws

APP_FILE=${ROOT_DIR}/${APP_NAME}
LOG_DIR=${ROOT_DIR}/logs
PID_FILE=${ROOT_DIR}/logs/${APP_NAME}.pid
LOG_FILE=${ROOT_DIR}/logs/${APP_NAME}.log

function check_pid() {
if [[ -f ${PID_FILE} ]];then
pid=`cat ${PID_FILE}`
if [[ -n ${pid} ]]; then
res=`ps -p ${pid}|grep -v "PID TTY" |wc -l`
return `echo ${res}`
fi
fi
return 0
}

function create_dir() {
if [ ! -d ${LOG_DIR} ]; then
mkdir -p ${LOG_DIR}
echo "log dir create success"
fi
}

function start() {
create_dir
check_pid
run_res=$?
if [[ ${run_res} -gt 0 ]];then
echo -n "${APP_NAME} is running already, pid="
cat ${PID_FILE}
return 1
fi
chmod +x ${APP_FILE}
cd ${ROOT_DIR}
source /etc/profile
nohup ${APP_FILE} &> ${LOG_FILE} &
echo $! > ${PID_FILE}
echo "${APP_NAME} start running, pid=$!"
}

function stop() {
pid=`cat ${PID_FILE}`
kill ${pid}
echo "${APP_NAME} stop"
}

function restart() {
pid=`cat ${PID_FILE}`
stop
start
}

function status() {
check_pid
run_res=$?
if [[ ${run_res} -gt 0 ]];then
echo "status: start"
else
echo "status: stop"
fi
}

function help() {
echo "$0 start|stop|restart|status|pid"
}

function pid() {
cat ${PID_FILE}
}

if [[ "$1" == "" ]]; then
help
elif [[ "$1" == "stop" ]];then
stop
elif [[ "$1" == "start" ]];then
start
elif [[ "$1" == "restart" ]];then
restart
elif [[ "$1" == "status" ]];then
status
elif [[ "$1" == "pid" ]];then
pid
else
help
fi

编程规范

  1. 编程规范好,可避免语言陷阱,可有利团队协作,有利项目维护。
  2. 正常的Go编程规范有两种:编译器强制的(必须的),gofmt格式化非强制的(非必须)。
  3. Go宣告支持驼峰命名法,排斥下划线法。
  4. 自定义原则:
    1. 统一工作区间,避免目录及文件名随意
    2. 规范变量/结构体/方法及接口名
    3. 规范注释
    4. 单元测试/程序效率等建议

两个等级: (S)建议,(M)必须。

  • (M)一个目录只包含一个包,模块复杂拆分子模块/子目录
  • (M)提交代码时gofmt格式化代码,golint检查代码(使用IDE时默认这两个工具会自动用到)
  • (S)json字符串建议使用反单引号
  • (M)文件名必须小写,允许下划线_,但头尾不能。避免与_test.go或者系统相关_386.go等冲突
  • (S)文件名以功能为指引,不需要再出现模块名
  • (M)目录名必须小写,允许中划线-,但头尾不能 不建议目录名出现下划线_
  • (M)包名必须全部小写,无下划线,越短越好,尽量不要与标准库重名,禁止通过中划线连接多个单词
  • (S)包名尽量与目录名一致
  • (M)函数名和结构体名必须为(驼峰命名法),最好不带特殊字符如划线等
  • (S)函数名建议动词或者动宾结构单词,结构体建议名词或者动名词
  • (S)常量和枚举名(大驼峰命名法),不允许下划线,第三方包例外。
  • (M)函数参数(小驼峰命名法),不能有下划线
  • (S)函数参数按紧密程度安排位置,同类型参数应该相邻
  • (S)参数不大于5个
  • (M)变量名不允许下划线,局部变量(小驼峰命名法),全局变量(大驼峰命名法)
  • (S)避免全局变量多使用,for循环可用单字母
  • (M)接口名(大驼峰命名法),不能下划线,名词
  • (M)复杂功能请多写注释备注,注释表达需清晰,不要啰嗦。注释标准暂时不强制,最好参考godoc,如包注释使用/**/,(大驼峰命名法),注释后空一行,函数注释写在函数上方等。
  • (S)建议少使用main方法测试,而是使用_test.go做测试

总而言之

文件名和目录名,包名都必须小写。

公有方法名、枚举名、接口名、常量、全局变量使用大驼峰命名法

私有方法名、局部变量和方法的参数使用小驼峰命名法

提示

Go语言中根据首字母的大小写来确定可以访问的权限。

无论是方法名、常量、变量名还是结构体的名称,如果首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用

可以简单的理解成:首字母大写是公有的,首字母小写是私有的