包的设计理念:使用包来封装不同语义单元的功能,更好的复用代码。
1. 包名的命名最好与所处文件夹保持一致
http 文件夹下的所有 .go 文件的包名都为 http, 声明如:package http
2. 文件夹命名最好为全小写,如: httputil
3. 不同文件夹下的包名可以相同,因为导入包时,是以全路径的方式导入的(本地包或远程包,go内置包只需引入包名即可)
一般情况下,包被导入之后会使用默认的包名作为名字
// 导入 http 包import "net/http"// 使用http.Get()
但是同时导入相同的包名时,为了避免包名冲突,可以重命名包名
// format包名冲突,查找 convert 包时报错:fmt redeclared as imported package nameimport ( "fmt" "demo/fmt" ) // 解决:重命名 import ( "fmt" demoFmt "demo/fmt" )
4. 因为 go 为了防止未被使用的包,避免代码变得臃肿,导入包之后不使用,这是不允许的,编译器会报错
import "fmt" // 但没有使用 fmt 报错:imported and not used: "fmt"
但是如果想让编译器不报错,可以在导入包路径的前面使用'空白标识符'下划线_ 来给包赋予一个空名字,
import _ "fmt"
空白标识符也可以使用的函数返回中,来忽略你不需使用的值
func main() { _, val := deSomething()}
5. 导入多个包时,一般是将 import 语句包装在一个导入块中
import ( "fmt" "strings" )
6. 导入远程包:import "远程地址"
// 导入viper远程包import "github.com/spf13/viper"
远程包没有找到时,可以使用 go get "包路径" 来下载包,go get 会递归下载所有能找到的依赖包
// 终端中执行以下代码,即可将viper下载到本地,一般会下载到 $GOPATH中go get "github.com/spf13/viper"
7. 导入本地自己写的包:import "包所在项目中的绝对路径",
// import "项目文件夹/fmt" 表示导入项目中的 fmt 包import "demo/fmt"
注意:如果不是使用第三插件比如 vendor 来管理包时,
项目文件一定要放在 $GOPATH 的 src 文件夹中(可以运行 go env 查看 $GOPATH),
否则会导致无法导入本地包的问题
8. go 编译器查找包的顺序:先在 $GOROOT 中查找,然后在 $GOPATH 中找,如果找到就会停止往下找,如果都找不到,则报错。
// 没有使用 go module等管理包工具,go-demo项目没有放在 $GOPATH/src 下时import "go-demo/fmt"// 报错信息cannot find package "go-demo/fmt" in any of:usr/local/go/src/go-demo/fmt (from $GOROOT)Users/Edward/go/src/go-demo/fmt (from $GOPATH)
9. 使用go module 来管理依赖包,此时项目可以不用放在 $GOPATH/src 路径下
// 使用 go module管理包// 初始化项目 demogo mod init demo// mod 导入本地包import "demo/fmt"// mod 管理远程包// 此时会将所有的第三方依赖包都下载到项目的 vendor 文件夹中go mod vendor
10. 每一个包都可以有任意多个 init 函数(一个包中的多个 .go 文件中都有 init 函数的情况)
//而这些 init 函数都会在 main 函数之前执行,所以可以在 init 函数中做一些设置包,或者初始化变量等工作
// fmt.gopackage fmtimport ( "fmt")func init() { fmt.Println("本地 fmt 包的 init 函数")}// util.gopackage utilimport "fmt"func init() { fmt.Println("util包的 init 函数")}// main.goimport ( "fmt" _"go-demo/fmt" _"go-demo/util")
11. main 函数是一个程序的主入口,运行 go build 之后,go 编译器会首先查找 main 包中的 main 函数。
// 尝试运行没有 main 函数的 .go 文件function main is undeclared in the main package// 如果找到,会编译成一个可执行文件,例如:windows会编译成一个 .exe 文件
12. 在命令行中使用 go 指令
// go 指令// 命令行是输入 go, 回车,会看到 go 所支持的命令列表
// 查看 go 环境相关信息, 如 GOROOT, GOPATH go env
// 编译文件, 编译成功后,会生成一个可执行文件go build main.go// 编译并执行文件// 尝试运行非main.go 文件会报错:cannot run non-main packagego run main.go// 清理 go build 生成的文件go clean// go doc 包名,查看相关包的文档go doc fmt// godoc -http=:6060 使用 godoc 开启一个web服务来查看文档// 但是,godoc 在1.13版本的时候被移除了,// 如果需要使用 godoc 命令,需要自己手动安装// 安装 godocgo get golang.org/x/tools/cmd/godoc// 查看 go 版本go version
go vet 审查常见的代码错误,每次对代码先执行 go vet 然后在将其签入到源代码库是一个很好的习惯。
fmt.Printf("main 函数", 3.14)
go fmt 格式化代码成和go源码类似的风格, 在提交代码到代码之前执行 go fmt 也是一个很好的习惯
// 格式化代码成和go源码类似的风格go fmt // 之前 if err != nil {return err} // 之后 if err != nil { return err }
大部分go 工具的命令都会接受一个包名作为参数,如果不包含文件名时,go工具会默认使用当前目录来编译
13. 注释
// 单行注释/**多行注释多行注释*/// 生成文档注释,包名路径下,包含一个 doc.go 的文件,// 并把注释加在包名声明之前/*这是一个文档注释*/import myfmt