Golang_8_数据

八、包

Go语言的源码复用是建立在包(package)基础之上的

8.1 包介绍

包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多内置包,如fmtosio等。

8.2 定义包

可以根据自己的需要创建自己的包,一个包可以理解为一个存放.go 文件的文件夹

所有.go文件都要在代码的第一行添加如下代码,声明该文件归属的包

package 包名

注意事项:

  • 一个文件夹下面只能有一个包,同样一个包的文件不能在多个文件夹下。
  • 包名可以不和文件夹的名字一样,包名不能包含-符号。
  • 包名为main的包为应用程序的入口包,编译时不包含main包的源代码时不会得到可执行文件。

8.3 可见性

标识符(如变量、常量、类型、函数等)的首字母大写就可以让标识符对外可见了

package pkg2

import "fmt"

// 首字母小写,外部包不可见
var a = 100

// 首字母大写,外部包可见
const Mode = 1

// 首字母小写,外部包不可见
type person struct {
    name string
}

// 首字母大写,外部包可见
func Add(x, y int) int {
    return x + y
}

func age()  {
		// 函数局部变量,外部包不可见,只能在当前函数内使用
    var Age = 18
    fmt.Println(Age)
}
  • 结构体内的字段 :
    • 结构体首字母大写 + 字段名首字母大写 = 外部包可访问
  • 接口内的方法:
    • 接口名首字母大写 + 方法名首字母大写 = 外部包可访问
// 结构体名首字母大写
type Student struct {
    Name 	string //包外可访问
    class	string //包外不可访问
}

// 接口名首字母大写
type Payer interface {
    init() //包内访问
    Pay() //包外可访问
} 

8.4 包的导入

例子:

目录结构和导包路径

src/github.com/aris/
├── basementStudy
│   ├── 8_package
│   │   ├── calc
│   │   │   └── calc.go
│   │   ├── main
│   │   │   └── main.go
│   │   └── pkg2
│   │       └── pkg2.go
│   └── main.go
└── hello
    └── main.go

导包写法:(src所在层为$GOPATH)

// main/main.go
package main

import (
    "fmt"
    "github.com/aris/basementStudy/8_package/pkg2"
)

// 当代码都在
func main() {
    fmt.Println(pkg2.Add(1, 2))
}

8.4.1 注意事项

  • import导入语句通常放在 文件开头包声明语句(package) 的下面。
  • 导入的包名需要使用双引号包裹起来。
  • 包名是从$GOPATH/src/后开始计算的,使用/进行路径分隔。
  • Go语言中禁止循环导入包。

8.4.2 单行导入

import "包1"
import "包2"

8.4.3 多行导入

import (
    "包1"
    "包2"
)

两种导包方法可以混用

8.5 自定义包名

package main

import (
    "fmt"
    c "github.com/aris/basementStudy/8_package/pkg2"
)

func main() {
    fmt.Println(c.Add(1,2))
}

8.6匿名导入包

导入包而不是用包的内部数据,可以匿名导入包。具体格式如下:

import (
	"fmt"
	calc "github.com/aris/basementStudy/8_package/pkg2"
	_ "github.com/astaxie/beego"
)

8.7 init()初始化函数

8.7.1 init()函数介绍

在Go语言程序执行时导入包语句会自动触发包内部init()函数的调用。

需要注意的是:

  • init()函数没有参数也没有返回值。
  • init()函数在程序运行时自动被调用执行不能在代码中主动调用它

包初始化执行顺序:全局声明 -> init() -> main()

package main
import "fmt"

// 1. 全局声明
var x int8 = 10
const pi = 3.14

// 2. init()
func init()  {
	fmt.Println(x)
}
// 3. main()
func main() {
	fmt.Println("Hello")
}

8.7.2 init()函数执行顺序

Go语言包会从main包开始检查其导入的所有包,每个包中又可能导入了其他的包。

Go编译器由此构建出一个树状的包引用关系,再根据引用顺序决定编译顺序,依次编译这些包的代码。

运行时,被 最后导入的包最先初始化 ,并调用其init()函数, 如下图示:

包之间的init()执行顺序


分享: