1.包的概述
任何包系统设计的目的都是为了简化大型程序的设计和维护工作,通过将一组相关的特性放进一个独立的单元以便于理解和更新,在每个单元更新的同时保持和程序中其它单元的相对独立性。这种模块化的特性允许每个包可以被其它的不同项目共享和重用,在项目范围内、甚至全球范围统一的分发和复用
- Go源码文件的第一行
package 包名
用来标记该源码文件属于哪个包- 一个目录(文件夹)下同级文件归属一个包,同一目录下不能定义不同的package
- 包名可以和目录名不同
- 包名为
main
的包对Go程序有特殊意义,main
包为应用程序入口包,Go语言编译程序会试图将main
包编译成一个可执行的二进制文件.一个可执行程序有且只有一个main
包main
包中一定需要有个main()函数,这个函数是Go程序的执行入口,无参数,无返回值.没有该函数程序就不能执行
2.包的作用
- 用于区分相同名字的函数,变量等标识符
- 当项目文件很多的时候,便于项目管理,项目模块化
- 控制函数,变量等访问范围
3. 包的导入 import
包的导入需要关键字
import
导入的包名使用双引号包围,包名是从
GOPATH
开始计算的路径,使用“/”
进行路径分隔包的的导入一般为(效果的一样的):
单行导入
package main import "包1" import "包2"
多行导入
import ( ”包 1 ” ”包 2 ” )
自定义引用包名:
有时导入的包路径后,包名太长了,对于书写不太友好,这时可以给包命一个
别名
如果给一个包自定义了一个别名,访问该包的数据的时候需要使用该别名来访问
package main
import (
// 导入自定义包 Ts就是自定义了包别名
Ts "GoNote/chapter5/demo1/tools"
// 导入系统包
"fmt"
)
匿名导入包:
如果只导入包,而不使用任何包内的结构和类型 ,也不调用包内的任何函数时,
可以使用匿名导入包, 需要注意的是即使匿名导入的包也会触发该包中的init()函数在导入包的前面加一个
_
就表示匿名导入
package main
import (
// 匿名导入自定义包
_ "GoNote/chapter5/demo1/tools"
// 导入系统包
"fmt"
)
4. 访问权限
Go语言中没有其他语言中的
访问控制符
: public ,protected,private 这样的关键字,.Go语言包中成员名称首字母大小写决定了访问权限:
- 首字母大写 可以被包外访问
- 首字母小写 仅能被包内成员访问
访问其他包内的函数的时候语法是
包名.函数名
,包名.变量名
使用.
符号进行访问
包文件结构
|
|__main
|____main.go
|__tools
|____calc.go
|____calculate.go
calc.go
package tools
// 外部可访问
var ToolsRes int
// 仅能包内部访问
var toolsRes int
// 外部可访问
var Err error
// 不可访问
func add(x, y int) (int, error) {
sum := x + y
return sum,nil
}
// 可以被外部访问到
func Calculator(x, y int, operate string) (int, error) {
switch operate {
case "+":
toolsRes,Err = add(x, y)
}
return toolsRes,Err
}
calculate.go
package tools
func Add(x,y int) (int ,error) {
// 调用了calc.go文件中的add方法,因为都是一个包内
res, err := add(x,y)
return res,err
}
main.go
package main
import (
// 导入自定义包
Ts "GoNote/chapter5/demo1/tools"
// 导入系统包
"fmt"
)
func main() {
// ToolsRes是tools包中定义的变量
Ts.ToolsRes ,Ts.Err = Ts.Calculator(90,10,"+")
if Ts.Err != nil{
fmt.Println(Ts.Err)
}
fmt.Println(Ts.ToolsRes)
// tools包中的calculate.go文件的中的函数
res1 ,err1 := Ts.Add(88,99)
if err1 != nil{
fmt.Println(err1)
}
fmt.Println(res1)
}
go run main.go
100
187
5. 初始化函数 init()
init()
函数是Go语言中保留的一个重要的函数,和main()
函数一样不需要任何参数也没有返回值
- 每个Go源码文件都可以有一个
init()
函数- 一个包中可以有多个
init()
函数,也可以一个都没有,也就是说init()
函数不是必须的init()
函数在程序执行之前(main()
函数执行之前) 被自动调用init()
不能被调用- 如果主程序中引入了很多包 ,那么
init()
初始化的顺序 深度优先的顺序初始化init()
通常做一些初始化的事情
示例代码的文件结构
|
|__main
|____main.go
|__tools
|____demo1.go
|__dao
|____dao.go
dao.go
package dao
import "fmt"
func init(){
fmt.Println("dao package init...")
}
func Say(){
fmt.Println("hello dao")
}
demo1.go
package tools
import (
"GoNote/chapter5/demo2/dao"
"fmt"
)
func init(){
fmt.Println("tools package once init ...")
}
func init(){
fmt.Println("tools package second init ... ")
}
func ToolsSay(){
dao.Say()
}
main.go
package main
import (
"GoNote/chapter5/demo2/tools"
"fmt"
)
import _ "GoNote/chapter5/demo2/tools"
func init(){
fmt.Println("main package init")
}
func main() {
fmt.Println("main do...")
tools.ToolsSay()
}
go run main.go
看执行结果
dao package init...
tools package once init ...
tools package second init ...
main package init
main do...
hello dao
网友评论