文章目录
- 包(package)
- 1. 定义
- 2. 导入
- 3. 初始化
- 4. 可见性
- 4. 注意
- 4.1 包声明
- 4.2 main包
- 4.3 包的导入
- 4.4标识符的可见性
- 4.5 包的初始化
- 4.6 避免命名冲突
- 4.7 包的路径和名称
- 4.8 匿名导入
- 4.9 使用Go Modules
包(package)
在Golang(通常简称为Go)中,包(Package)是一个非常重要的概念,它用于组织代码,提高代码的可维护性和可重用性。包的概念类似于其他编程语言中的模块或命名空间。
1. 定义
在Go中,每个文件都属于一个包。包的声明位于文件的最顶部,使用package
关键字。
package main
2. 导入
要在Go文件中使用其他包中的代码,需要使用import
关键字导入该包。
import "fmt"
导入包时,可以使用别名来避免命名冲突或简化代码
import f "fmt"
3. 初始化
当一个包被导入时,Go会执行该包中的init
函数(如果有的话)。
init
函数在包的每个文件中都可以定义,但只能有一个(Go会自动合并)。
init
函数没有参数,也没有返回值,并且不能被其他函数调用。它主要用于包的初始化工作。
package mypackage
import "fmt"
func init() {
fmt.Println("mypackage is initialized")
}
4. 可见性
在Go中,通过首字母大小写来控制标识符(如变量、函数、类型等)的可见性。首字母大写的标识符是导出的,可以被其他包访问;首字母小写的标识符是未导出的,只能在包内部访问。
package package_demo
// 导出的变量
var PublicVar = "I am public"
// 未导出的变量
var privateVar = "I am private"
// 导出的函数
func PublicFunc() {
fmt.Println("Public function")
}
// 未导出的函数
func privateFunc() {
fmt.Println("Private function")
}
main.go文件
package main
import (
"Golang/package_demo"
_ "Golang/package_demo"
"fmt"
)
func main() {
fmt.Println("Hello, 世界")
// 测试包的可见性
fmt.Println(package_demo.PublicFunc())
fmt.Println(package_demo.PublicVar)
}
输出结果
package package_demo init
Hello, 世界
public function
public var
main.go文件
package main
import (
"Golang/package_demo"
_ "Golang/package_demo"
"fmt"
)
func main() {
fmt.Println("Hello, 世界")
// 测试包的可见性
fmt.Println(package_demo.PublicFunc())
fmt.Println(package_demo.PublicVar)
fmt.Println(package_demo.privateVar)
fmt.Println(package_demo.PrivateFunc())
}
输出结果
# command-line-arguments
./main.go:15:27: undefined: package_demo.privateVar
./main.go:16:27: undefined: package_demo.PrivateFunc
4. 注意
4.1 包声明
- 每个Go源文件都必须在文件的第一行声明它所属的包,使用
package 包名
的语法。 - 包的声明通常与所在的文件夹名称相同,但这不是强制性的,不过为了管理方便,建议保持一致。
4.2 main包
-
main
包是特殊的,它是程序的入口点。如果一个包被声明为main
,并且其中包含了main
函数,那么这个包就可以被编译成一个可执行文件。 -
main
函数必须放在main
包下,否则程序无法编译执行。
4.3 包的导入
- 要在代码中引用其他包的内容,需要使用
import
关键字。 - 导入包的语法是
import "包的路径"
,路径是从$GOPATH/src/
或模块根目录开始计算的,使用/
进行路径分隔。 - 可以使用单行导入或多行导入的方式。
- 如果包名较长,可以为导入的包设置别名,使用
import 别名 "包的路径"
的语法。
4.4标识符的可见性
- 在Go语言中,如果一个标识符(如变量、常量、类型、函数等)的首字母大写,则它是对外可见的(public),可以被其他包访问。
- 如果首字母小写,则它是包内可见的(private),只能在当前包内使用。
4.5 包的初始化
- 在Go语言程序执行时,导入包语句会自动触发包内部
init()
函数的调用。 -
init()
函数没有参数也没有返回值,它在程序运行时自动被调用执行,不能在代码中主动调用它。 - 如果有多个包被导入,Go编译器会构建出一个树状的包引用关系,并根据引用顺序决定初始化顺序。
4.6 避免命名冲突
- 在同一个包下,不能有相同的函数名或全局变量名,否则会导致重复定义的编译错误。
- 如果不同的包中有相同名称的标识符,并且这些包都被导入到同一个文件中,那么需要通过包名来区分这些标识符。
4.7 包的路径和名称
- 包的路径应该是唯一的,以避免命名冲突。
- 包名可以包含小写字母和数字,但不能包含特殊字符(如
-
)或大写字母(虽然技术上可以,但通常不推荐)。
4.8 匿名导入
- 如果只希望导入包而不使用包内部的数据,可以使用匿名导入的方式,即
import _ "包的路径"
。 - 匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中,但不会在代码中使用该包提供的标识符。
4.9 使用Go Modules
- 对于新项目,建议使用Go Modules来管理依赖关系。
- 在项目的根目录下创建
go.mod
文件,并运行go mod init
命令来初始化模块。 - 使用Go Modules时,包的路径通常是相对于模块根的路径。
- 包下的以
_test.go
结尾的文件,是测试文件,不会在普通编译时包含。