1、包(package)
- go语言中使用包来支持代码模块化和代码复用,一个包由一个或多个go源码文件(.go结尾的文件)组成
- go语言提供了很多内置包,如fmt
1.1、定义包
可以根据自己的需要创建自定义包。一个包可以简单理解为一个存放.go文件的文件夹
package packagename
1、包名一般是小写
2、包名一般和所在目录同名,也可以不同,包名中不能包含特殊符号
3、包名一般使用域名作为目录名,能保证包名的唯一性,如GitHub项目的包一般会放到GOPATH/src/github.com/userName/projectName 目录下
4、包名为main的包为应用程序入口包,这种包编译后会得到一个可执行文件,而编译不包含main包的源代码则不会得到可执行文件
5、一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下
1.2、可见性
- 如果想在一个包中引用另外一个包里的标识符(如变量、常量、类型、函数等)时,该标识符必须是对外可见的(public)。在Go语言中只需要将标识符的首字母大写就可以让标识符对外可见了
- 在Go语言中是通过标识符的首字母大/小写来控制标识符的对外可见(public)/不可见(private)的。在一个包内部只有首字母大写的标识符才是对外可见的
package demo
import "fmt"
// 包级别标识符的可见性
// num 定义一个全局整型变量
// 首字母小写,对外不可见(只能在当前包内使用)
var num = 100
// Mode 定义一个常量
// 首字母大写,对外可见(可在其它包中使用)
const Mode = 1
// person 定义一个代表人的结构体
// 首字母小写,对外不可见(只能在当前包内使用)
type person struct {
name string
Age int
}
// Add 返回两个整数和的函数
// 首字母大写,对外可见(可在其它包中使用)
func Add(x, y int) int {
return x + y
}
// sayHi 打招呼的函数
// 首字母小写,对外不可见(只能在当前包内使用)
func sayHi() {
var myName = "七米" // 函数局部变量,只能在当前函数内使用
fmt.Println(myName)
}
//结构体中的字段名和接口中的方法名如果首字母都是大写,外部包可以访问这些字段和方法。例如:
type Student struct {
Name string //可在包外访问的方法
class string //仅限包内访问的字段
}
type Payer interface {
init() //仅限包内访问的方法
Pay() //可在包外访问的方法
}
1.3、包的引入
要在当前包中使用另外一个包的内容就需要使用import关键字引入这个包,并且import语句通常放在文件的开头,package声明语句的下方。
import "包的路径"
// 单行导入
import "day02/package1"
// 多行导入
import (
"day02/test"
"fmt"
)
1、导入的包名需要使用双引号包裹起来
2、Go语言中禁止循环导入包
当引入的多个包中存在相同的包名或者想自行为某个引入的包设置一个新包名时,可以指定一个在当前文件中使用的新包名
例如,在引入fmt包时为其指定一个新包名f
import f "fmt"
这样在当前这个文件中就可以通过使用f来调用fmt包中的函数了
f.Println("Hello world!")
如果引入一个包的时候为其设置了一个特殊_作为包名,那么这个包的引入方式就称为匿名引入,目的主要是为了加载这个包,从而使得这个包中的资源得以初始化,被匿名引入的包中的init函数将被执行并且仅执行一遍
import _ "github.com/go-sql-driver/mysql"
1、匿名引入的包与其他方式导入的包一样都会被编译到可执行文件中
2、Go语言中不允许引入包却不在代码中使用这个包的内容,如果引入了未使用的包则会触发编译错误
2、init初始化函数
- 每一个go源文件中,都可以定义任意个初始化函数
- 初始化函数不接收任何参数也没有任何返回值,也不能在代码中主动调用它
- 程序启动时,初始化函数会按照声明的顺序自动执行,所有在包中声明的init函数都将被串行调用并且仅调用执行一次
- 每个包初始化时都是先执行依赖的包中声明的init函数,再执行当前包中声明的init函数,确保在main函数开始执行时所有依赖包初始化完成
package main
import "fmt"
var x int8 = 10
const pi = 3.14
func init() { //init函数先被执行
fmt.Println("x:", x)
fmt.Println("pi:", pi)
sayHi()
}
func sayHi() {
fmt.Println("Hello World!")
}
func main() {
fmt.Println("你好,世界!")
}
x: 10
pi: 3.14
Hello World!
你好,世界!