go 语言的包
Go 语言包的基本概念
Go语言 包的基本概念
Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案。Go语言中为我们提供了很多内置包,如 fmt、os、io 等。
包时结构化代码的一种方式:每个程序都是由包(通常简称为pkg)的概念组成,可以使用自身的包或者从其他包中导入内容
如同其他一些编程语言中的类库或者命名空间的概念,每个Go文件有且仅属于一个包。一个包可以由许多以 .go
为扩展名的源文件组成,因此文件名和包名一般来说都是不同的。
必须在源文件中非注释的第一行指明这个文件属于与哪个包 package pacakgeName
语句,通过该语句声明自己所在的包。package main
则表示一个可独立执行的程勋,每个Go应用程序都包含一个名为main的包。
一个应用程序可以包含不同的包,而且即使只使用main包,也不必包所有的代码都写在一个巨大的文件里:可以使用一些较小的文件,并且在每个文件非注释的第一行使用package main
来指明这些文件文件都属于main包。如果打算编译报名不是main的源文件,如 pack1,编译后产生的对象文件将会是pack1.a
而不是可执行程序。另外,要注意的是所有的包名都应该使用小写字母
标准库
标准库API:https://studygolang.com/pkgdoc
在Go的安装文件里包含了一些可以直接使用的包,即标准库。在Windows 下,标准库的位置在Go根目录下的子目录pkg\windoes_amd64中;在Linux下,标准库在Go根目录的子目录 pkg\linux_amd64中.
一般情况下,标准包会存放在$GOROOT/pkg/\$GOOS_GOARCH/
目录下. GO的标准库包含了大量的包,(如:fmt 和os),但是也可以创建自己的包
如果想要构建一个程序,则包和包内的文件够必须以正确的顺序进行编译。包的依赖关系决定了器构建顺序。
属于同一个包的源文件必须全部一起被编译,一个包即是编译时的一个单元,因此根据惯例,每个目录都只包含一个包
如果对一个包进行更改或者重新编译,所有引用了这个包的客户端程序都必须全部重新编译
Go中的包模型采用了显示依赖关系的机制来达到快速编译的目录。编译器会从后缀名为.go
的对象文件(需要且只需要这个文件)中提取传递依赖关系型的信息
如果A.go 依赖B.go,而B.go 又依赖C.go:
- 编译C.go,B.go,然后是A.go
- 为了编译A.go ,编译器读取的是B.go,而不是C.go
这种机制对于编译大型的项目时可以显著提升编译速度
示例
在目录example3 下,有目录cat 和main 。 在 cat 目录下有cat.go文件。 在main目录下有main.go文件
复制//cat.go 文件
package cat
import "fmt"
var Name string = "Tom"
var Age int = 5
//初始化函数
func init() {
fmt.Println("this is cat package")
fmt.Println("init 函数修改前", Name, Age)
Name = "jack"
Age = 3
fmt.Println("init 函数修改后", Name, Age)
}
复制//main.go文件
package main
import (
"dev_code/day9/example3/cat"
"fmt"
)
//调用其他包,程序加载顺序 cat.go中全局变量-->cat.go中的init()函数--->main.go中的main()函数
func main() {
fmt.Println("猫的名字:", cat.Name)
fmt.Println("猫的年龄:", cat.Age)
}
//执行main.go文件 输出结果:
this is cat package
init 函数修改前 Tom 5
init 函数修改后 jack 3
猫的名字: jack
猫的年龄: 3
程序执行顺序
Go程序 的执行(程序启动)顺序如下:
- 按顺序导入所有被main包引用的其他包,然后在每个包中执行如下流程
- 如果该包又导入了其他包,则从第一部开始递归执行,但是每个包只会被导入一次
- 然后一相反的顺序在每个包中初始化常量和变量,如果该包含有init 函数的话,则调用该函数。
- 在完成这一切后,main也执行同样的过程。最后调用执行程序
在example5 目录下有demo包,main包,test包。 在demo包中有demo.go文件。在main包中有main.go文件。在test包中有test.go文件
复制//demo.go文件
package demo
import "fmt"
var Name string = "this is demo package "
var Age int = 20
func init() {
fmt.Println("this is demo init()")
fmt.Println("demo.package.Nam:", Name)
fmt.Println("demo.package.Age:", Age)
Name = "this is demo New"
Age = 200
fmt.Println("demo.package.Nam:", Name)
fmt.Println("demo.package.Age:", Age)
}
复制//test.go文件
package test
import (
// 在引用的包前面加上 _ 表示只加载这个包,但是不进行引用包里的函数和变量
_ "dev_code/day9/example4/demo"
"fmt"
)
var Name string = "this is test package"
var Age int = 10
func init() {
fmt.Println("this is test init()")
fmt.Println("test.package.Nam:", Name)
fmt.Println("test.package.Age:", Age)
Name = "this is test New"
Age = 100
fmt.Println("test.package.Nam:", Name)
fmt.Println("test.package.Age:", Age)
}
复制//main.go文件
package main
import (
"dev_code/day9/example4/test"
"fmt"
)
func main() {
//main --->test--->demo
fmt.Println("main.package", test.Name)
fmt.Println("main.package", test.Age)
}
//执行main.go文件输出结果:
this is demo init()
demo.package.Nam: this is demo package
demo.package.Age: 20
demo.package.Nam: this is demo New
demo.package.Age: 200
this is test init()
test.package.Nam: this is test package
test.package.Age: 10
test.package.Nam: this is test New
test.package.Age: 100
main.package this is test New
main.package 100
导入包时空白标识符的作用
如果导入了一个包,却没由使用它,则会在构建时引发错误,如imported andnot used
所以,我们可以使用空白标识符_
来解决
方法一:
声明一个全局空白标识符(在main()函数之前),该标识符从 未使用的包中访问符号。
复制package main
import "os"
var _ = os.Open
func main() {
}
方法二:
在未使用的包前加上一个空白标识符。只初始化加载该包,而不去使用该包的函数和变量
复制package main
import _ "os"
func main() {
}
包的别名
在不同的父目录下,存在相同名字的包。比如,在example4和example5目录下,都有cat 包。那么,不管是导入,还是使用包里的函数或者变量,都很不方便,容易混淆。
此时我们可以在导入包的时候,在前面加上包的别名,在使用的使用,使用别名调用即可
复制package main
//导入fmt 包,同时,设置a 为fmt 包的别名
import a "fmt"
func main() {
//在使用时,使用别名进行调用
a.Println("通过包的别名进行调用")
}
//输出结果:
通过包的别名进行调用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界