Go基础|第2章:Package

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1087 次阅读

Golang.jpg

Synopsis: 每个 Go 程序都是由包(package)组成,每个包的代码都可以作为很小的复用单元,被其他项目引用。源代码中可以通过 import 来导入官方提供的标准库中的包(standard library)或别人写的第三方包(比如 github.com/gorilla/mux )

1. 包命名

Go 程序由 main 包中的 main() 函数开始执行

Go 程序给 包(package) 命名的惯例是使用包所在目录的名字,这让用户在导入包的时候,就能清晰地知道包名

另外,给包及其目录命名时,应该使用简洁、清晰且全小写的名字,这有利于开发时频繁输入包名,比如 Go 标准库中的 fmtlogos

2. 包导入

源代码中使用 import 关键字来导入 Go 标准库或第三方包

Go 编译器会去 %GOROOT%\src%GOPATH%\src 目录下查找是否有对应的包:

C:\Users\wangy>go env
set GOROOT=c:\go
set GOPATH=C:\Users\wangy\go

所以,导入路径(import path) 应该是相对路径。比如,使用 import "fmt" 导入 fmt 包(目录为 %GOROOT%\src\fmt\)、使用 import "net/http" 导入 http 包(目录为 %GOROOT%\src\net\http

为了防止第三方包与标准库重名,第三方包的导入路径一般都包含托管源代码的主机名、组织名称等,比如 github.com/gin-gonic/gingolang.org/x/net

按照约定,程序包名称与导入路径的最后一个元素相同

假设我要导入第三方包 github.com/gin-gonic/gin

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

当我们不使用 Go Modules 包管理器时,会提示找不到 gin 包:

D:\MyCode\mad-forum>go run app.go
app.go:3:8: cannot find package "github.com/gin-gonic/gin" in any of:
        c:\go\src\github.com\gin-gonic\gin (from $GOROOT)
        C:\Users\wangy\go\src\github.com\gin-gonic\gin (from $GOPATH)

如果我们使用了包管理器 Go Moduels 的话,那么当 Go 编译器在 %GOROOT%\src%GOPATH%\src 目录下找不到第三方包时,就会 自动将包下载到 %GOPATH%\pkg\mod 目录中

1. 初始化
D:\MyCode\mad-forum>go mod init madmalls.com/mad-forum
go: creating new go.mod: module madmalls.com/mad-forum

2. 运行时自动处理包的依赖关系
D:\MyCode\mad-forum>go run app.go
go: downloading github.com/gin-gonic/gin v1.4.0
go: extracting github.com/gin-gonic/gin v1.4.0
go: downloading github.com/mattn/go-isatty v0.0.7
go: downloading github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: downloading github.com/golang/protobuf v1.3.1
go: downloading gopkg.in/go-playground/validator.v8 v8.18.2
go: downloading github.com/ugorji/go v1.1.4
go: downloading gopkg.in/yaml.v2 v2.2.2
go: extracting github.com/mattn/go-isatty v0.0.7
go: extracting github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: extracting github.com/golang/protobuf v1.3.1
go: extracting gopkg.in/go-playground/validator.v8 v8.18.2
go: extracting github.com/ugorji/go v1.1.4
go: extracting gopkg.in/yaml.v2 v2.2.2
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

3. 包声明

每个包都在一个单独的目录里,包下面可以有多个以 .go 为扩展名的文件

不能把多个包放到同一个目录中,也不能把同一个包的文件拆分到多个不同目录中。这意味着,同一个目录下的所有 .go 文件必须声明为同一个包名。所以,fmt 包中的文件都以 package fmt 开头

一个包只需要在其中一个 .go 文件的最前面添加 包注释 即可

4. 解决包名冲突

假设我要同时导入标准库中两个不同的 rand 包,可以分别为导入的包设置一个别名,这样后续可以用别名来调用各自包中的函数:

package main

import (
    crand "crypto/rand"
    mrand "math/rand"

    "fmt"
)

func main() {
    a := mrand.Int() // 伪随机数
    b := make([]byte, 8)
    crand.Read(b) // 通过加密算法生成的安全的伪随机数
    fmt.Println(a, b)
}

强烈建议不要使用 import . "fmt" 这种形式来导入包!

有时候,你可能需要导入一个包,但是并不会使用这个包中所导出的变量或函数等,只是想在导入时自动先执行它的 init() 函数,那么可以使用 空白标识符(_) 来重命名这个包,否则 Go 编译器会编译失败(为了避免代码变得臃肿,所以 Go 不允许你导入一个包却不使用它)

import (
    "database/sql"
    "fmt"

    _ "github.com/lib/pq"  // go connect to postgresql
)

5. go get 下载包

go get 命令可以下载第三方远程包,以及它所依赖的其它包:

go get -u -v github.com/gorilla/mux

当然,现在有了包管理器 Go Moduels,你只需要在源代码中写上 import "github.com/gorilla/mux" 即可,当你执行 go rungo build 命令时,会自动帮你下载这些依赖包

6. 查看包文档

6.1 go doc 与 godoc

你可以使用 go doc 命令在本地查看 Go 标准库的文档:

C:\Users\wangy>go doc fmt
C:\Users\wangy>go doc fmt.Println

或者,访问 HTML 格式的在线文档: https://golang.org/pkg/ (国内可以访问 https://go-zh.org/pkg/

或者,安装 godoc 工具,它可以启动一个 Web 服务器,并以网页形式显示文档。默认国内是无法安装 golang.org/x/.. 下的包的,但是有了 Go ModulesGOPROXY 之后,这都不是事:

D:\MyCode\mad-forum>go mod init madmalls.com/mad-forum
D:\MyCode\mad-forum>go get -u -v golang.org/x/tools/cmd/godoc

启动 Web 服务器:

D:\MyCode\mad-forum>godoc -http=:6060

然后,打开浏览器,访问 http://127.0.0.1:6060/ 即可!

6.2 GoDoc

GoDoc 网站可以为存放在 Github / Bitbucket / Launchpad / Google Project Hosting 等上面的开源 Go 包提供文档查询功能,比如 https://godoc.org/github.com/gorilla/mux

分类: Go 基础
标签: go doc go get godoc package
未经允许不得转载: LIFE & SHARE - 王颜公子 » Go基础|第2章:Package

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.