在Unix/C的项目中,核心在于Makefile,一个架构怎样,从Makefile中就可以看出来一些端倪。而在go中,可以使用gomake或者直接使用make都可以进行项目的设计。本文将从Unix/C项目中整理一部分常用的技巧,结合go语言自身特点,讨论一下如何进行go语言项目的搭建,本文中大部分的总结同时使用与Unix/Linux下C语言项目的实践,因为本身就是从相关大型项目中抽取的部分实践经验。
Makefile的次佳实践
最佳实践永远是下次才会出现,因此将过去在Unix/C项目中的一部分好的经验进行整理如下。
规则1:使用include方式
Makefile也像编码一样,要讲究重用和可扩,因此在include进行变量和Option以及路径等定义,然后进行统一重用,比如在Makeilfe中这样写:
include comset
- 1
而在comset文件中则进行定义变量等:
[root@host31 src]# cat comset
###############################################################################
#MAINTAINER: [email protected]
###############################################################################
###############################################################################
#COMMAND
###############################################################################
CC = go
BUILD = ${CC} build
CLEAN = ${CC} clean
TEST = ${CC} test
INSTALL= $(CC) install
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
规则2:Makefile分层
Makefile和comset进行按照定义进行分层,好处在于调整方便,比如调节某一个Option只针对某一个模块(目录),此种方式就非常方便
规则3:宏传递方式
类似Unix/C下的-D,传递宏开关到系统之中,go是这样做的:-X main.SOMEMODE=XX
示例如下:
[root@host31 src]# cat main.go
package main
import "fmt"
var SOMEMODE string
func main() {
fmt.Println("Hello, SOMEMODE=", SOMEMODE)
}
[root@host31 src]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
结果确认:
[root@host31 src]# go build --ldflags "-X main.SOMEMODE=ON" -o hello main.go
[root@host31 src]# ./hello
Hello, SOMEMODE= ON
[root@host31 src]#
- 1
- 2
- 3
- 4
规则4:活用伪目标
为了避免is up to date等信息的出现,活用伪目标规则是一个不错的选择,比如docker等的Makefile即为如此。示例:
.PHONY: all build install fmt clean
- 1
规则5:活用fmt和vet
活用go vet和go fmt进行语法检查和代码格式整理,这样能保证代码编写风格的一致以及语法的最低要求。
规则6:活用依赖关系
利用Makefile的依赖规则,比如保证在make build之前一定会做vet和fmt进行语法检查和格式整理,强制检查,保证质量于每次基本动作之中,提前发现问题也是新一轮的DevOps文化在反馈回路中所倡导的。
规则7:明确结果文件
缺省go build缺省会以当前目录名成作为结果文件名,而在实际go build的时候建议加入-o参数指定结果名称,即使一样也能清晰看出,看不见的地方COC没有问题,这种非常扎眼的地方还是不要让人有Magic Box的的感觉为好。
规则8:命令的使用方式
使用$(shell 命令)的方式即可,可以使用管道以处理一行需要的复杂情况,但尽量不要写太奇怪而失去可读性。使用例:读取当前目录的父目录设定为GOPATH
export GOPATH=$(shell pwd |xargs dirname)
- 1
Package关联规则
规则9:package名与文件夹名一致
package名称最好跟文件夹名称一致
规则10:package引用方式
相同package之间的引用,不要带包名,不同package之间虽然可以通过使用import的写法可以是不带包名的方式,建议还是带上包名以表示确定引用出处较好。
包的引用,一般有如下四种方式:
项番 | 方式 | 详细 | 说明 |
---|---|---|---|
No.1 | . | import . 包名 | 引用的时候无需使用包名 |
No.2 | 别名 | import 别名 包名 | 引用的时候使用别名进行引用 |
No.3 | _ | import _ 包名 | 不是为了倒入此包,而是单纯地为了调用其init函数而已 |
No.4 | import 包名 | 根No.2的方式类似,区别在于没有别名,直接用包名 |
参考
可以参看如下项目的例子:https://github.com/liumiaocn/cycle
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow