Go项目的目录结构

一直搞不懂golang是怎么组织项目目录结构的,后来看了Golang项目目录结构组织总算弄明白一些了。整体来说,golang使用目录+包来管理的,比起python来说确实麻烦一些。具体往后看,本文基于上面的连接进行总结。

1. 准备工作

首先,需要设置一个环境变量GOPATH,简单地说,import的包都在这个变量里面找,包括go get得到的包也都是安装在这里面。

一个GOPATH一般有3个子目录:

src (存放源码,最重要的)
pkg (存放编译后的代码)
bin (存放编译后的可执行文件)

一般来说pkg和bin目录不用我们创建,go build 或者 go install的时候就会自己创建了,golang的安装目录就是一个GOPATH,这里我们添加一个路径到GOPATH,这里引用原文的例子
首先,创建一个GOPATH变量,如果已有就加在后边,用;分开

2. 新建项目

<proj>
  |--<src>
       |--<a>
           |--<a1>
                |--al.go
           |--<a2>
                |--a2.go
       |--<b>
           |--b1.go
           |--b2.go
       |--<c>
           |--c.go
  |--<pkg>
  |--<bin>

各文件代码:
a1.go:

1
2
3
4
5
6
7
package a1

import "fmt"

func PrintA1() {
fmt.Println("a/a1")
}

a2.go:

1
2
3
4
5
6
7
package a2

import "fmt"

func PrintA2() {
fmt.Println("a/a2")
}

b1.go:

1
2
3
4
5
6
7
package b

import "fmt"

func printB1() {
fmt.Println("b.b1")
}

b2.go:

1
2
3
4
5
6
7
8
package b

import "fmt"

func PrintB() {
printB1()
fmt.Println("b.b2")
}

c.go:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"a/a1"
"a/a2"
"b"
)

func main() {
a1.PrintA1()
a2.PrintA2()
b.PrintB()
}

最后在c.go的目录下go run c.go
结果:

a/a1
a/a2
b.b1
b.b2

若执行go install c则将会同时生成pkg目录和bin目录,且可执行文件在bin目录里面。

3. 总结

golang的项目目录组织结构说起来其实就两个细节:
import 的是目录,从GOPATH里面src目录开始的目录
package 是给函数调用的。
比如c.go 里面,import “a/a1” 指的是GOPATH/scr/a/a1 目录,而c.go里面的a1.PrintA1() 中的a1是a1.go 里面的packae a1,比如说:
如果 a1.go 的路径变成 a/a11a1.go 里面改成 package aaa ,那么 c.go 就变成了:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"a/a11"
"a/a2"
"b"
)


func main() {
aaa.PrintA1()
a2.PrintA2()
b.PrintB()
}

4. 补充(据说不推荐)

golang的import是可以不依赖GOPATH的,但是据说是不推荐的作法。

1
2
3
|--<a>
|--a.go
|--main.go

a.go:

1
2
3
4
5
6
7
8
9
package a

import (
"fmt"
)


func PrintA() {
fmt.Println("aaa")
}

main.go:

1
2
3
4
5
6
7
8
9
10
11
package main

import (
"./a"
"fmt"
)


func main() {
a.PrintA()
fmt.Println("main")
}

结果:

1
2
aaa
main

可见,golang也是支持相对引入的