Go中package的使用
executable package 和 utility package
如果一个包是main package,那么go install会创建一个二进制文件,运行时会调用main函数。(所以要执行一个单独的Go程序就必须有 package main声明)
如果不是main package,那么go install会创建一个package archive文件。
注:GO111MODULE必须置为auto
详解go install命令
go install <package>命令寻找指定<package>目录中有package main这个package declaration的文件。
- 如果找到了,那么go就知道这是一个可执行程序,要在bin目录创建一个二进制文件 —— executable package
- 如果没找到,那么go就会在pkg目录下这创建一个package archive (
.a)文件 —— utility package 注意,同一个目录下(不包括子目录)的.go文件不能既有package main的声明又有package <其他>的声明,否则会报错:
can't load package: package exercisepkg: found packages mypkg (hello.go) and main (thisismain.go) in /Users/zty/go/src/exercisepkg
export members
只要全局变量名开头字母大写,这个变量就可以export(可以被其他包import)
注:本文中变量名可以指变量,const,函数等等
import syntax
import <package> (<package>是一个路径)
go首先从GOROOT/src目录中找这个路径,如果没找到再去GOPATH/src目录中找。
比如fmt包是一个go标准包,它在GOROOT/src下;我们自定义的包可以放在GOPATH/src下
访问export members
用package delaration时的名字.变量名
辨析:包名pacakge name与包声明pacakge declaration
包名:GOROOT/src或GOPATH/src下的目录路径(可以是subpath)
包声明:比如在文件第一行声明package hello(这个hello可以与目录名不同)
使用:
-
import或go install时用包名,也就是包路径go install后生成的.a文件的在pkg/darwin_amd64中的路径与包目录在GOROOT/src或GOPATH/src下的路径相同,例如GOPATH/src/abc/abcde用go install后,生成GOPATH/pkg/darwin_amd64/abc/abcde.a -
导入后使用包中变量时,用包声明时的名字.xxx
比如如果包声明为
package hello,那么访问hello包中的name变量时就用hello.Name。因为在import一个包时,go会创建一个以包声明时的名字命名的变量。如果要更改的话,可以用package alias,比如
import (hl "hello"), 就可以用hl.Name; 如果只向initialize一个包,但不使用它的话,可以用_作为alias,比如import (_ "hello")
package scope
package scope是一个区域,在其中声明的变量能被全包访问。这个区域就是包中所有文件的topmost block,这个区域中可以定义包的全局变量,定义全局变量时也可以调用函数通过函数的返回值来初始化
全局变量初始化
与函数中的变量初始化不同的是,它可以以任意的顺序初始化,只要没有循环引用。比如:
var a int = b
var b int = c
var c int = 2
在package scope中可以这样使用,但在函数中就不可以了
因为在package scope中是以“initialization cycle”的方式进行初始化的,比如在上例中,最开始c被声明,下一个initialization cycle中b被声明,再下一个initialization cycle中a被声明。
定义全局变量时也可以调用函数通过函数的返回值来初始化,比如var d = somefunc()
init函数
在包中的任意位置都可以定义init function,同一个文件中可以有多个init function。按文件名字母表顺序执行各文件中的init function,同一文件中按init function定义顺序执行。
init函数的作用主要是初始化全局变量,包中所有init函数执行完才会执行main function
一个包被导入或被执行时会执行它的init function,但所有init都只会执行一次,即使一个包被导入多次
程序执行顺序
初始化: 本包导入的包初始化(递归初始化) -> 本包全局变量初始化 -> 本包的所有init function
初始化后,执行本包的main函数
安装第三方包
$ go get -u github.com/jinzhu/gorm
上述命令从http://github.com/jinzhu/gorm这个URL中得到所有文件,然后保存到src/github.com/jinzhu/gorm目录下。
所以我们导入时使用import "github.com/jinzhu/gorm"即可。要把我们的包发布供别人使用时也是直接发布到github上即可。