任何包系统设计的目的都是为了简化大型程序的设计和维护工作,通过将一组相关的特性放进一个独立的单元以便于理解和更新,在每个单元更新的同时保持和程序中其它单元的相对独立性。这种模块化的特性允许每个包可以被其它的不同项目共享和重用,在项目范围内、甚至全球范围统一的分发和复用
Go源码文件的第一行 package 包名 用来标记该源码文件属于哪个包一个目录(文件夹)下同级文件归属一个包,同一目录下不能定义不同的package包名可以和目录名不同包名为main 的包对Go程序有特殊意义,main 包为应用程序入口包,Go语言编译程序会试图将main包编译成一个可执行的二进制文件.一个可执行程序有且只有一个main包main 包中一定需要有个main()函数,这个函数是Go程序的执行入口,无参数,无返回值.没有该函数程序就不能执行包的导入需要关键字 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" )Go语言中没有其他语言中的访问控制符 : public ,protected,private 这样的关键字,.
Go语言包中成员名称首字母大小写决定了访问权限:
首字母大写 可以被包外访问首字母小写 仅能被包内成员访问访问其他包内的函数的时候语法是 包名.函数名, 包名.变量名 使用 . 符号进行访问
包文件结构
| |__main |____main.go |__tools |____calc.go |____calculate.gocalc.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 187init() 函数是Go语言中保留的一个重要的函数,和main() 函数一样不需要任何参数也没有返回值
每个Go源码文件都可以有一个init()函数一个包中可以有多个init()函数,也可以一个都没有,也就是说init()函数不是必须的init() 函数在程序执行之前(main()函数执行之前) 被自动调用init() 不能被调用如果主程序中引入了很多包 ,那么init() 初始化的顺序 深度优先的顺序初始化init() 通常做一些初始化的事情示例代码的文件结构
| |__main |____main.go |__tools |____demo1.go |__dao |____dao.godao.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