包(package)是 Go 组织代码的单位:一个目录一组 .go 文件,文件开头的 package 声明定名字。下面分概念、作用域、导入三块说。
1. 包的概念
定义
包是一个目录,其中包含一个或多个 .go 文件。每个 Go 源文件的开头都有一个 package 声明,用于指定文件属于哪个包。包的名称通常与目录名称相同。
作用
- 封装:将相关功能和数据封装在一起,隐藏内部实现细节。
- 组织:将代码组织成模块,便于管理和维护。
- 重用:通过包的导入和调用实现代码的重用。
2. 包的作用域
作用域规则
- 包内作用域:在同一包内,所有的标识符(如函数、变量、常量、类型)的作用域是包内的。包内的私有标识符(以小写字母开头)只能在包内访问。
- 包外作用域:包外的代码无法访问包内的私有标识符(以小写字母开头)。只有以大写字母开头的标识符是公共的,可以被包外的代码访问。
示例代码:
go
// 文件: mathutils.go
package mathutils
// Public function (exported)
func Add(a, b int) int {
return a + b
}
// Private function (not exported)
func subtract(a, b int) int {
return a - b
}go
// 文件: main.go
package main
import (
"fmt"
"path/to/your/project/mathutils"
)
func main() {
sum := mathutils.Add(10, 5) // 可以访问
// diff := mathutils.subtract(10, 5) // 编译错误:无法访问
fmt.Println("Sum:", sum)
}3. 包的导入
导入包
用 import 导入别的包,需要时给包起个别名。
- 基本导入:直接导入包,使用包的名称作为前缀来访问其导出的标识符。
- 别名导入:给导入的包指定一个别名,以简化代码或避免名称冲突。
示例代码
基本导入
go
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Square root of 16 is", math.Sqrt(16)) // 使用 math 包中的 Sqrt 函数
}别名导入
go
package main
import (
fmt "fmt" // 给 fmt 包指定别名
math "math" // 给 math 包指定别名
)
func main() {
fmt.Println("Square root of 16 is", math.Sqrt(16)) // 使用别名访问包中的函数
}导入多个包
go
package main
import (
"fmt"
"math"
"time"
)
func main() {
fmt.Println("Square root of 16 is", math.Sqrt(16))
fmt.Println("Current time:", time.Now())
}导入和忽略包 如果导入一个包但不使用它,可以使用 _(空白标识符)来导入该包以执行其初始化函数,但避免编译器警告未使用的包。
示例代码:
go
package main
import (
_ "path/to/some/package" // 导入但不使用该包
)
func main() {
// 这里可以执行代码,但不会直接使用导入的包
}总结
- 包(Package):是代码的组织单元,用于将相关的功能和数据封装在一起。每个包有自己的作用域,包内的标识符的访问权限取决于其首字母的大小写。
- 作用域:包内的标识符的作用域是包内的,只有以大写字母开头的标识符可以被包外访问。
- 导入:使用
import语句来导入包,支持基本导入和别名导入。可以导入多个包,并使用_导入包以执行其初始化函数但不直接使用它。
判断一个标识符能不能被包外看到,只看首字母:大写导出,小写包内私有;_ 导入只跑包的初始化,不占名字。