002-go 项目结构
2018-02-04 22:13
267 查看
本节告诉你如何使用 go 来写一个计算类的库,这个库包含了 2 个函数,一个计算 2 数之和,另一个计算两数之差,并且掌握 go 的项目结构。
在 tutorial 文件夹下面创建一个文件夹 package,还有子文件夹 calc, testcalc,如图 1.
图1 目录结构
add.go 与 sub.go
这两个文件非常简单,add.go 里有一个名为 Add 的函数,sub.go 里有一个名为 Sub 的函数。
main.go
不出意外,你会出现下面的结果(如果你是从第 1 篇跟着我做的话):
图2 运行报错
接下来,很重要,为了能让你的程序成功运行,你需要配置一个名为
再执行一次:
图3 运行结果
从第 1 篇开始我就让你吭哧吭哧建立了一堆文件夹,你也不知道是干啥的,为啥要这么搞。现在可以来说明一下。
为了让 go 编译工具能管辖
所有被添加到
如果你的
工作目录就应该有工作目录的样子,它下面必须有三个子目录,分别是
所有的源代码放在
如果你觉得这个工作目录名字不够酷,你甚至可以再添加一个工作目录,比如叫
记住了,
然鹅,上面说的包名的定义并不是绝对的,所以我前面加了『一般来说』这 4 个字。如果哪个 go 的包名不符合上面的规则,你可以把他打死。(哈哈,你来打我啊)。
这是个不推荐的做法,你应该写成
除了我们自己编写的包外,还引入了一个
在 go 里,程序都是通过
练习:
上面包名没有符合 go 语言习惯,包路导入径是
把 add.go 中的函数名改成 add 再试试,另外 main.go 里调用的时候也别忘记改成 add.
再写两个函数,分别是乘法 Mul 和 除法 Div.
你能把 go 的函数和 c 语言函数作个对比吗?
1. 目录与文件
创建文件夹在 tutorial 文件夹下面创建一个文件夹 package,还有子文件夹 calc, testcalc,如图 1.
$ mkdir package $ cd package $ mkdir calc testcalc
图1 目录结构
add.go 与 sub.go
这两个文件非常简单,add.go 里有一个名为 Add 的函数,sub.go 里有一个名为 Sub 的函数。
// add.go package hello func Add(a int32, b int32) int32 { return a + b; }
// sub.go package hello func Sub(a int32, b int32) int32 { return a - b; }
main.go
// main.go package main import ( "fmt" "gopl/tutorial/package/calc" ) func main() { var a int32 = 1 var b int32 = 2 sum := hello.Add(a, b) diff := hello.Sub(a, b) fmt.Printf("%d + %d = %d\n", a, b, sum) fmt.Printf("%d - %d = %d\n", a, b, diff) }
2. 运行 testcalc 下的 main.go
$ go run main.go
不出意外,你会出现下面的结果(如果你是从第 1 篇跟着我做的话):
图2 运行报错
接下来,很重要,为了能让你的程序成功运行,你需要配置一个名为
GOPATH的环境变量,它的值是
~/gogo
$ export GOPATH=~/gogo
再执行一次:
图3 运行结果
3. go 项目的基本结构
好了进入正题,我知道你心里有一万头羊鸵在奔腾:你特么的想说啥啊?好吧我错了,保证没有下次了。从第 1 篇开始我就让你吭哧吭哧建立了一堆文件夹,你也不知道是干啥的,为啥要这么搞。现在可以来说明一下。
3.1 工作目录
首先gogo文件夹,取啥名字无所谓,因为我电脑上已经存在了一个叫
go的文件夹了,我实在找不到更好的名字,所以就取了个
gogo这样的名字。未来,我打算把所有 go 的程序都放在这里面。
为了让 go 编译工具能管辖
gogo文件夹,所以才有了后面添加
export GOPATH=~/gogo这样的动作。当然了,go 肯定可以管理很多文件夹的,你只要继续往
GOPATH里追加文件夹路径即可。
所有被添加到
GOPATH的路径,都可以称之为工作目录。
如果你的
gogo没有被 go 认同,就会出现图 2 中的结果,找不到包。因为它并不是合法的 go 工作目录。
工作目录就应该有工作目录的样子,它下面必须有三个子目录,分别是
src,
pgk,
bin,就算我不解释,你也能猜测它们是干啥的。
所有的源代码放在
src下面。比如在我们这里,
src下面有一个文件夹
gopl,这个系列的 go 文章产生的源代码都放在这下面(gopl 是那本神书的名字缩写)。如果你有什么想法,也想搞个学习笔记的文件夹,你应该在 src 下面创建一个你的文件夹,比如叫
lihailewodego什么的(名字有点长,但是它真的可以啊)。
如果你觉得这个工作目录名字不够酷,你甚至可以再添加一个工作目录,比如叫
godafahao,然后追加到
GOPATH里,像这样
export GOPATH=~/gogo:~/godafahao,不要忘记再添加三个子目录啊。
3.2 包
在 main.go 中,引入了 2 个包,一个是 go 自带的,另一个是我们自己编写的。import ( "fmt" "gopl/tutorial/package/calc" )
记住了,
gopl/tutorial/package/calc不是包名,它是包导入路径。一般来说,包名是包导入路径的最后一个目录名。说人话,就是说上面第 2 个包的包名是
calc.
然鹅,上面说的包名的定义并不是绝对的,所以我前面加了『一般来说』这 4 个字。如果哪个 go 的包名不符合上面的规则,你可以把他打死。(哈哈,你来打我啊)。
gopl/tutorial/package/calc这个路径真正包名叫
hello,实际上,它是在 add.go 和 sub.go 第一行定义的(称之为包声明):
package hello
这是个不推荐的做法,你应该写成
package calc而不是上面那样,这样你在 main.go 中使用这个加减法包时可以使用
calc.Add(...)而不是
hello.Add(...)这种反人类的写法了。
除了我们自己编写的包外,还引入了一个
fmt包,这个包的导入路径是
fmt,包名也是
fmt,在
main.go中,我们使用了这个包的
Printf函数输出结果到屏幕。
在 go 里,程序都是通过
package来组织管理的,不同的包提供不同的功能,这有点像其它语言的库的概念。go 语言自身提供了各种各样的包供我们使用,另外,我们也可以使用第三方的包来扩展程序。
3.3 package main
main包是 go 语言里特殊的包,程序的入口就在这里。入口函数名和 C 语言一样,也叫 main.
4. 总结
掌握 go 语言的项目结构。练习:
上面包名没有符合 go 语言习惯,包路导入径是
gopl/tutorial/package/calc,但包名却不是
calc,请你修正过来。
把 add.go 中的函数名改成 add 再试试,另外 main.go 里调用的时候也别忘记改成 add.
再写两个函数,分别是乘法 Mul 和 除法 Div.
你能把 go 的函数和 c 语言函数作个对比吗?