内容简介:在上一篇教程中,学院君带着大家搭建起了本地开发环境,并且编写了第一个 Go 程序,向世界问好。不过在实际开发过程中,直接调用编译器进行编译和链接(调用Go 语言的设计者作为行业老将,自然不会忽略这一点。说到这里,我们来看看 Go 语言的主要设计者都是何方神圣:
工程管理概述
在上一篇教程中,学院君带着大家搭建起了本地开发环境,并且编写了第一个 Go 程序,向世界问好。不过在实际开发过程中,直接调用编译器进行编译和链接(调用 go build
或 go run
命令)的场景很少,因为在项目工程中不会简单到只有一个源文件,往往有很多源文件并且源文件之间会有相互依赖的关系,如果这样一个文件一个文件逐步编译,那简直无法想象。
Go 语言的设计者作为行业老将,自然不会忽略这一点。说到这里,我们来看看 Go 语言的主要设计者都是何方神圣:
个顶个的都是大神级人物。早期 Go 语言使用 makefile
作为临时方案,到了 Go 1 发布时引入了强大无比的 Go 命令行工具 ,Go 命令行 工具 彻底消除了工程文件的概念,完全用目录结构和包名来推导工程结构和构建顺序。想想 C 语言编译、链接和安装可执行程序的繁琐步骤,首先要通过 configure
脚本对特定平台进行检测,比如是否包含 GCC 等编译工具,然后生成 Makefile 文件,该文件定义了编译、链接规则,为下一步编译工作做准备,接下来就是执行 make
命令进行编译工作,最后再执行 make install
命令完成应用程序的安装,经历过这些步骤才可以实现将 C 程序源代码编译为可执行程序。
与之相比,Go 语言则要简单的多,针对只有一个源文件的情况(如上篇教程所示),引入工程管理看起来比较多余,因为直接用 go run
和 go build
搞定,下面我们通过 Go 语言构建一个简单的计算器项目来演示 Go 语言的基本工程管理方法。
编写计算器工程源码
我们假设这个工程被划分为两个部分:
- 可执行程序,名为
calc
,内部只包含一个calc.go
文件,该文件是计算器程序的入口文件; - 算法库,名为
simplemath
,每个计算操作对应于一个同名的 Go 文件,比如add.go
用于计算加法运算。
这样,对应的工程目录组织应该如下所示:
然后我们来编写每个 Go 文件的源代码, src/calc/calc.go
的源码如下:
package main // 引入其它包 import ( "fmt" "os" "simplemath" "strconv" ) // 定义一个用于打印程序使用指南的函数 var Usage = func() { fmt.Println("USAGE: calc command [arguments] ...") fmt.Println("\nThe commands are:\n\tadd\t计算两个数值相加\n\tsqrt\t计算一个非负数的平方根") } // 程序入口函数 func main () { /* * 用于获取命令行参数,注意程序名本身是第一个参数, * 比如 calc add 1 2 这条指令,第一个参数是 calc */ args := os.Args // 除程序名本身外,至少需要传入两个其它参数,否则退出 if args == nil || len(args) < 3 { Usage() return } // 第二个参数表示计算方法 switch args[1] { // 如果是加法的话 case "add": // 至少需要包含四个参数 if len(args) != 4 { fmt.Println("USAGE: calc add <integer1><integer2>") return } // 获取待相加的数值,并将类型转化为整型 v1, err1 := strconv.Atoi(args[2]) v2, err2 := strconv.Atoi(args[3]) // 获取参数出错,则退出 if err1 != nil || err2 != nil { fmt.Println("USAGE: calc add <integer1><integer2>") return } // 从 simplemath 包引入 Add 方法进行加法计算 ret := simplemath.Add(v1, v2) // 打印计算结果 fmt.Println("Result: ", ret) // 如果是计算平方根的话 case "sqrt": // 至少需要包含三个参数 if len(args) != 3 { fmt.Println("USAGE: calc sqrt <integer>") return } // 获取待计算平方根的数值,并将类型转化为整型 v, err := strconv.Atoi(args[2]) // 获取参数出错,则退出 if err != nil { fmt.Println("USAGE: calc sqrt <integer>") return } // 从 simplemath 包引入 Sqrt 方法进行平方根计算 ret := simplemath.Sqrt(v) // 打印计算结果 fmt.Println("Result: ", ret) // 如果计算方法不支持,打印程序使用指南 default: Usage() } }
这段代码相信对于有 PHP 编程基础的人来说,都不困难,需要注意的是在 Go 语言中,通过 var
来声明变量,并且可以将匿名函数赋值给变量以便后续使用,此外,还可以通过 :=
运算符来声明并初始化变量,这个时候,不需要通过 var
声明该变量,比如 args := os.Args
就是如此,需要明确的是,虽然看起来有点和动态语言声明变量类似,但与 PHP 不同,Go 是强类型语言,只不过底层会自动根据赋值判断对应变量的类型,如果你试图声明一个没有初始化值的变量,就会报错,关于 Go 语言变量声明和初始化我们后面还会详细介绍,这里简单了解下即可。
接下来,我们编辑 src/simplemath/add.go
代码如下:
package simplemath func Add(a int, b int) int { return a + b }
以及 src/simplemath/sqrt.go
代码如下:
package simplemath import "math" func Sqrt(i int) int { v := math.Sqrt(float64(i)) return int(v) }
配置 GOPATH 环境变量
为了能够构建这个工程,需要先把这个工程的根目录加入到环境变量 GOPATH
中,上篇教程中,我们介绍过 GOPATH
,并且提到其默认值是 ~/go
(其中 ~
表示用户家目录),除此之外,我们还可以为 GOPATH
配置多个路径值,以便我们在任意地方组织编写 Go 项目代码。假设计算器项目根目录 calc
目录位于 ~/go
下,如果是基于 GoLand 进行开发的话,可以通过「首选项(Preferences)->Go->GOPATH」界面来进行设置:
在 Project GOPATH 中新增一条路径即可,然后点击「Apply」按钮,很简单。此外,在 Unix-Like 系统中,还可以通过编辑 ~/.bashrc
文件,并添加下面这行代码:
export GOPATH=~/go/calc
然后执行以下命令应用该设置来完成 GOPATH
的自定义设置:
$ source ~/.bashrc
在 Windows 中,则可以通过配置环境变量 GOPATH
来实现,将你的项目根目录完整路径拷贝过去就好
了。和 PATH
环境变量一样, GOPATH
也可以支持一次配置多个路径,并且路径和路径之间用冒号分隔。
GOPATH
的用处是 Go 语言在编译程序时,会从 GOPATH
配置的路径里面去查找源文件并完成构建。
构建 Go 工程
设置完 GOPATH
后,现在我们开始构建工程。假设我们希望把生成的可执行文件放到 calc/bin
目录中,需要执行的一系列指令如下:
cd ~/go/calc mkdir bin cd bin go build calc
这样就会在 calc/bin
目录下生成可执行文件 calc
:
然后我们就可以执行 calc
程序了:
从上面的构建过程中可以看到,真正的构建命令就一句:
go build calc
这就是为什么说 Go 命令行工具是非常强大的。我们不需要写 makefile
,因为这个工具会替我们分析,知道目标代码的编译结果应该是一个包还是一个可执行文件,并分析 import
语句以了解包的依赖关系,从而在编译 calc.go
之前先把依赖的 simplemath
编译打包好。Go 命令行程序制定的目录结构规则让代码管理变得非常简单。
当然,这里只是一个最简单、最基本工程管理的构建示例,后面我们还会就更复杂的工程项目管理进行介绍,比如工程组织、文档与代码风格、跨平台开发、单元测试、打包分发等。学习过程中有任何问题,欢迎通过下面的评论或加入社群与我讨论。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Go中的工程管理
- Go 语言教程之工程管理
- “阿波罗”登月中的工程管理一瞥
- 基于体系工程理念的大型复杂军事信息系统核心能力建设工程管理模式研究
- 测试工程师如何使用 CODING 进行测试管理
- NuCypher 工程师告诉你,链上私人数据如何安全存储与管理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Machine Learning
Kevin Murphy / The MIT Press / 2012-9-18 / USD 90.00
Today's Web-enabled deluge of electronic data calls for automated methods of data analysis. Machine learning provides these, developing methods that can automatically detect patterns in data and then ......一起来看看 《Machine Learning》 这本书的介绍吧!