几个 概念
- project: project 即项目,这是最大的单位
- package: package 即包,包是程序的概念,程序又不同的包组成
- directory: directory 即文件夹,里面可以放文件 file
- file: file 即文件,一般加后缀的那个就是了,如 main.go
- func: func 即函数,编程的基本单位,在 file里
file 名什么影响也没有
我们建立
└── dd
└── ff.go
自然 file 的名字和 directory 没有任何关系,如果我们在 ff.go 中
package pp
表示 ff.go 文件位于 pp package 中,这没有任何问题, 把 pp 任意改为其他,也没有 error,
这说明 file 的名字和 directory, package 等都没有任何关系,可以随便建
package 和 directory 名没有关系
└── dd
└── ff.go
directory 名叫 dd, 而 file 名叫 ff.go, 在 ff.go 中, 代码如下
package pp
并没有报错,这说明此 package 被命名为 pp , 但是 directory 名是 dd,说明 package 和 directory 名没有关系
我们可以在此 director 下多建几个文件试试
└── dd
└── ff.go
└── ff1.go
在 ff1.go 中我们同样写代码如下
package pp
同样没有表错,说明 package 和 directory 名没有关系
一个 directory 下只能有一个 package
刚刚我们建立了
└── dd
└── ff.go
└── ff1.go
ff.go 里
package pp
ff1.go 里
package pp
这并没有报错,当如果我们把 ff1.go 里改为
package pp1
我们会得到一个 error Multiple packages in directory: pp, pp1
这说明同一个 directory 下的所有文件必须是同一个 package, 即 一个 directory 下只能有一个 package
import package 的 path 是 directory 名
我们建立
└── main.go
└── dd
└── ff.go
在 ff.go 中
package pp
type Haha struct {
a int
b string
}
在 main.go 中
package main
现在要在 main.go 中,也就是在 main package 中引用 pp package 的 Haha 类型, 需要 import pp package,
在 main.go 中使用 Haha 时,会自动 import,我们发现
import (
"projectName/dd"
)
然后使用 Haha 时是 dd.Haha ,dd 是 package 所在 directory 的名字,那我们可以猜测导包时导入的是 package 所在的 directroy 名,而不是 package 名,现在我们验证一下。
把 dd 改为 dd1 ,我们发现
import (
"projectName/dd1"
)
导包时的名字自动变为了 dd1 ,这验证了我们的猜想。实际上 import 后面是 GOPATH 的相对路径。
同时如果我们把 Haha 改为 haha, 即首字母小写,我们发现 main package 是无法使用 pp package 中的 haha struct 的。同时如果我们细心一点,就会发现平时不同 package 间引用时,type 或 func 都是需要大写的。如常见的fmt.Println
这里如果我们反过来,把 Haha strict 放在 main.go 中,即 main package 中,我们会发现无论是否大小,在其他 package ,如这里的 pp package 中还是无法使用。我们知道 在 main package 要使用其他 package 里声明的东西需要 import 其他 package,这里也说明其他 package 是无法使用 main 包里声明的东西,
故 main package 一般都建议代码量够少,同时一个 project 里如果有多个 main package,不同 main package 想要使用对方
声明的东西也是不行的。
不同 directory 下的 同名 package 是不同的 package
即一个 package 只能位于一个 directory 中,从上面我们知道使用其他 package 里的东西时需要 import。
我们建立
└── dd
└── ff.go
└── cc
└── mm.go
└── main.go
ff.go 里
package pp
type Dd_s struct{
}
mm.go 里
package pp
type Cc_s struct{
}
现在我们建立了分别在 dd 和 cc directory 里建立了 pp package,现在我们要在 main.go 里调用它们
我们先调用 dd 里的 Dd_s
package main
import "projectName/dd"
func main() {
a := pp.Dd_s{}
}
然后我们再调用 cc 里的 Cc_s
package main
import (
pp "projectName/dd"
pp2 "projectName/cc"
)
func main() {
a := pp1.Dd_s{}
b := pp2.Cc_s{}
}
我们会发现调用第二个 pp package 时, import 会自动给它们 alias, 不光 import package 时 import 的是 directory name,这里进一步说明 不同 directory 里的同名package 是不同的package
上面我们 的 directory 都是平行的,其实子目录和父目录也是不同的包
一个 project 至少有一个 main package
换句话说可以有多个 main package
我们建立
└── dd
└── ff.go
在 ff.go 里
package pp
func s () {
}
即在 非 main 里没有 main func, 然后 run 我们会发现抱 error Main file has non-main package or doesn't contain main function
, 然后我们把 ff.go 改为
package pp
func main() {
fmt.Printfln("Hello World!")
}
我们 run 一下,同样抱 error Main file has non-main package or doesn't contain main function
现在我们又改
package main
func s() {
fmt.Println("Hello World!")
}
又报 error Main file has non-main package or doesn't contain main function
我们再改
package main
func main() {
fmt.Println("Hello world")
}
现在成功了,我们根据上面可以得出 build and run 的结论,即只有 main package 含有一个 main func 时,才可以 run
我们知道不同 directory 都是不同的 package, 那我们多建个 main package 试试
└── dd
└── ff.go
└── cc
└── mm.go
ff.go
package main
func main() {
fmt.Println("Hello dd!")
}
mm.go
package main
func main() {
fmt.Println(Hello cc!)
}
我们分别 run ff.go和 mm.go, 我们发现都是成功的,现在我们可以发现一个 project 可以有多个 main package ,而且它们 run 都是分开的,当然如果 project 里没有 main package 的话,那 project 就不能 run 了,这是自然的。
一个 package 最多只能有一个 main 函数
无论是一个 package 中 不同 file 里
└── dd
└── ff.go
└── ff1.go
ff.go
func main {
fmt.Println("Hello ff!")
}
ff1.go
func main {
fmt.Println("Hello ff1!")
}
会报 error contains more than one main function
还是 一个 package 里一个 file 里
func main {
fmt.Println("Hello ff1!")
}
func main {
fmt.Println("Hello ff1!")
}
报 error 'main' redeclared in this package
总结
- 在一个 project 中
- 至少有一个 main package,可以有多个 main package,
- build and run 时是先找到 main package, 然后找到这个 main package 中的 main func,然后开始 build,故一个 project 中可以 run 不同的 main package
在 一个 main package 中,只能有一个 main func, 当然可以没有 main func ,不过那样的话其他 package 又不能 使用 main package 里的东西,这个 main package 没有 main func, 这个 package 也就不能 build, 那这个 package 显然没有用处
在一个 directory 中都是一个 package ,并且他们的名字没有关系,只要 一个 directory 里只有一个 package 就行
虽然 directory name 和 package name 没有关系,但是一般建议 directory name 和 package name 取成一样的,不然的话容易弄混
不同 directory 里取相同名的 package, 这些 package 是不同的 package, 如果要同时使用这两个 package 里的内容, import 的时候需要 alias pakcage name
一般项目结构就是 一个 project 里,只要一个 main package, 然后里面一个 main file,一个 main func, 这就是 project 的启动文件,然后各自建立 directory , dirctory name 即 package name, 然后在 direcory 里建立不同 的file,file name 表明这个 file 里主要干些什么