Go 包相关

时间:2024-01-27 12:28:19

包的作用

   Go语言中的包是源码的集合,是一种高级的代码复用方案。

   在Go语言中拥有很多自带的包,如fmtos等。

   我们也可以进行一个自定义的包。

定义包

   一个文件只能归属于一个包。

   如main旧是一个可执行文件包,编译main包会得到一个可执行文件,如果是非main包则不会得到一个可执行文件。

   包的命名不可以和文件夹名字相同,并且不可含有特殊符号。

   如下的定义一个test包。

   注意:一个main包不可被其他文件进行导入

package test

import (
	"fmt"
)

// F1 是一个公开的方法
func F1(){
	fmt.Println("test包中的F1")
}

可见性

   在包内,如果标识符首字母为大写则代表该标识符是对外可见的。

   反之则是该包的私有标识符。

package test

import (
	"fmt"
)

// F1 是一个公开的方法
func F1(){
	fmt.Println("test包中的F1")
}

// Person 是一个公开的结构体
type Person struct{
	name string  // name是一个私有的结构体字段
} 

导入包

注意事项

   导入包时使用import关键字进行导入。同时它有一些以下的注意事项:

   import导入语句通常放在文件开头包声明语句的下面。

   导入的包名需要使用双引号包裹起来,同时包名则是文件夹的名称。

   包名是从$GOPATH/src/后开始计算的,使用/进行路径分隔。

   Go语言中禁止循环导入包。

单行导入

   单行导入是使用较少的导入方式,格式如下:

import "包1"
import "包2"

  

多行导入

   多行导入使用括号进行包裹,可在一个import下导入多个包,格式如下:

import (
	"包1"
	"包2"
)

别名导入

   我们可以为导入的包取一个自定义名字,格式如下:

import 别名 "包的路径"

   或者在多行导入时这样使用,内置的包会放在上面,自定义或第三方包会放在下面。

import (
	"内置包"
	
	别名 "第三方包路径"
)

匿名导入

   匿名导入的意义在于我们只导入这个包,但是并不会调用其中的某些方法。

   如链接数据库时就会使用到匿名导入。

   匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中。

   语法如下:

import _ "包的路径"

示例演示

   目录结构如下:

- bin
- pkg
- src
	- yunya.com
		- module
			- test.go // 这是一个自定义包
		- main.go // 启动文件

   我们想在main.go中使用test.go中的功能,则可进行如下的导入:

package main

import "fmt"
import "yunya.com/module"  // 注意,包是所属文件夹的名称

func main() {
	test.F1()
	fmt.Println("执行fmt中的Println")
}

init函数

函数介绍

   init()函数是一个go文件作为包时将自动触发的一个函数(如果没有该函数则忽略)。

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

   如下所示:

   test.go

package test

import (
	"fmt"
)

// F1 是一个公开的方法
func F1(){
	fmt.Println("test包中的F1")
}

// Person 是一个公开的结构体
type Person struct{
	name string  // name是一个私有的结构体字段
}

func init(){
	fmt.Println("自动执行我啦")
}

   当调用该包时,自动执行init,打印结果如下:

package main

import "fmt"
import "yunya.com/module"  // 注意,包是所属文件夹的名称

func main() {
	test.F1()
	fmt.Println("执行fmt中的Println")
}

// 自动执行我啦
// test包中的F1
// 执行fmt中的Println

main与init

   如果一个go文件是一个main包,同时在其中声明了那么main()函数与init()函数执行谁先谁后呢?

   结果如下:

package main // 单独执行,main包不可被导入

import (
	"fmt"
)

func main() {
	fmt.Println("执行main")
}

func init() {
	fmt.Println("执行init")
}

// 执行init
// 执行main

执行顺序

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

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

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

   包之间的init()执行顺序

多个main

   当一个项目下有多个main时,则不用进行导入。依次执行即可,在编译时会自动将其整合成一个可执行文件。

   注意:多个main时需要防止变量冲突的问题,同时多个main中没有可见性这一说法,由于会整合成一个可执行文件,所以它们彼此之间都是可见的

   目录结构如下:

- bin
- pkg
- src
	- yunya.com
		- start.go // 启动文件 main包
		- s1.go // main包
		- s2.go // main包

   具体代码如下:

// -- start中的内容
package main

import (
	"fmt"
)

func main() {
	fmt.Println(s1)
	fmt.Println(s2)
}

// -- s1中的内容
package main

var s1 = string("s1变量")

// -- s2中的内容
package main

var s2 = string("s2变量")

   执行命令时,使用以下命令:

go run start.go s1.go s2.go

   或者直接使用以下命令,编译该文件夹下所有的maingo文件进行整合处理:

go build