红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Go语言编程笔记
  4. 正文

Go语言编程笔记11:使用包组织代码

2021年11月28日 1264点热度 0人点赞 0条评论

image-20211108153040805

图源:wallpapercave.com

Go语言的代码是以包的形式组织的,本篇笔记将阐述包相关的一些内容。

基本概念

创建

环境变量

Go有两个和包相关的系统环境变量:GOROOT和GOPATH。前者是Go语言本身的安装目录,后者是用户的“Work Space”,也就是一般的编写代码的目录。

这两个目录都主要由以下三个字目录构成:

  • bin:二进制可执行文件。

  • pkg:编译后的包组件。

  • src:源码。

对于GOROOT的目录来说,子目录所对应的内容都是Go语言本身的内容,比如bin下有go.exe和gofmt.exe,前者是Go的主要工具,编译和执行Go程序都要靠它,后者可以格式化代码。src下则存放Go的标准库的源码,Go是一个开源语言,所以自身相关的所有组件都可以以源码的形式保存在这里。

和GOROOT类似,GOPATH下的src目录存放用户编写的代码。

在Windows下,安装Go的安装包后会自动创建环境变量GOPATH,并设置为C盘用户目录下的子目录go。如果需要自定义代码编写目录,可以直接修改用户环境变量中的GOPATH。

如果要检查GOPATH是否设置正确并生效,可以在命令行下执行:

❯ go env
...省略
set GOPATH=D:\workspace\go

如果指向的目录下缺少src子目录,需要手动创建。

命名规则

按照Go的命名习惯,包名的命名需要符合以下规则:

  • 全部为小写字母组成,中间不应该使用连字符或下划线,如果是两个单词组成,直接连接,比如strconv。

  • 应该在没有歧义的情况下尽量使用简写,比如fmt。

  • 包名应当与代码所在的目录尽量保持一致。

确定好包名后,在GOPATH指向的目录下的src目录中就可以用包名创建目录,作为存放包代码的目录。

包中的代码文件命名和数量都没有规定,可以开发者自行决定。

包级常量、变量

可以在函数外创建包级常量或变量:

package pkgvar
​
var Num1 int
var Num2 int
​
const pi float32 = 3.14

可以在包内的函数或者包外访问这些包级变量。

init函数

有些包需要在被导入时进行一些初始化行为,这些内容可以通过init函数实现:

package pkgvar
​
var Num1 int
var Num2 int
​
const pi float32 = 3.14
​
func init() {
    Num1 = 1
    Num2 = 2
}

进行测试:

package main
​
import (
    "fmt"
    "go-notebook/ch11/pkgvar"
)
​
func main() {
    fmt.Println(pkgvar.Num1)
    fmt.Println(pkgvar.Num2)
    // 1
    // 2
}

导入

可以使用import导入包,对于标准包,可以直接导入:import "fmt"。对于第三方包,需要按照在GOPATH下的目录结构进行导入:import "go-notebook/ch11/pkgvar"。

重命名导入

如果导入的包和当前代码文件中的变量名出现重复,则需要在导入时重新命名:

package main
​
import (
    "fmt"
    pkgv "go-notebook/ch11/pkgvar"
)
​
func main() {
    var pkgvar string
    fmt.Println(pkgvar)
    fmt.Println(pkgv.Num1)
    fmt.Println(pkgv.Num2)
    // 1
    // 2
}

匿名导入

在某些时候,可能需要导入一个包,但并不需要在当前代码中使用,比如说在系统刚启动时,对负责管理当前系统的配置的包进行初始化:

package config
​
var Configs map[string]interface{}
​
func init() {
    Configs["version"] = "1.0.0"
}

此时可以使用匿名变量_作为包的导入名称:

package main
​
import (
    _ "go-notebook/ch11/config"
)
​
func main() {
}

分发代码

当你编写好代码后,需要考虑如何将代码分发给他人,有一些编程语言在这方面很出色,比如Python,自带一个第三方库的分发平台pypi.org,可以很方便地分发代码。

Go的分发方式相对简单,只要将代码上传到Git协议的代码仓库,就可以借用git工具来上传和下载代码。

上传

这里以Github为例,详细的使用信息见从零开始Github。

下载

下载代码可以通过Go自带的工具go get进行,不过前提是已经安装好了git工具:

❯ go get github.com/icexmoon/go-notebook/

正常情况下,go工具会自动从指定的代码仓库下载源码到GOPATH下的相应目录,无论当前的工作目录是什么。

如果无法下载,需要检查你电脑的网络,比如如果对命令行git使用了代理,以访问Github,则可能需要关闭go工具的代理:❯ go env -w GO111MODULE=off,某些情况下这两者是有冲突的。

理论上go get很好用,不仅会下载目标代码,还会一同下载关联的第三方代码,但实际使用时因为众所周知的缘故可能会出现各种各样的问题,如果实在无法使用,可以尝试直接使用git工具。

安装

一般情况下我们可以通过go build对当前目录下的go程序进行编译,并生成相应的可执行文件:

❯ go build main.go
❯ .\main.exe
1
2

这样做有个缺陷是生成的可执行文件和源码混杂在一起,并且让直接使用该程序变得麻烦,毕竟需要每次使用前都要切换到对应目录下才行。

除了上面的方式以外,我们可以直接安装目标程序到GOPATH的bin目录:

❯ go install github.com/icexmoon/go-notebook/ch11/main1
❯ main1
1
2

go install可以自动检测指定的目录下的 go 代码的入口函数,进行编译后安装到$GOPATH/bin目录,并且以所在包的名字进行命名。

这里方便起见我添加了$GOPATH/bin目录到用户环境变量path中,这样就可以直接在命令行执行通过go install安装的任何程序。

查看包文档

代码的注释相当重要,某些情况下甚至比代码本身更重要。所以我们需要明确如何正确地编写Go的注释和查看注释。

编写注释

这里以一个简单的包作为示例:

//Package input read string from keyboard
package input
​
import (
    "bufio"
    "os"
)
​
//GetLine will read a line from keyboard and return
func GetLine() (string, error) {
    scanner := bufio.NewReader(os.Stdin)
    return scanner.ReadString('\n')
}

包注释需要编写在源码文件的最上方,package声明之前,需要注意的是,即使该包是由多个源码文件组成,也仅需要在其中一个源码中写入包注释。

如果包注释的内容较多(超过三行),可以在包中添加一个文件doc.go来专门存放包注释。

包注释按照惯例以Package pkg_name xxx开头,其中pkg_name应当替换为包名。

函数注释卸载函数定义的上方,按惯例以函数名称开头,比如示例中的GetLine xxx。

通常我习惯于在函数注释中加入参数和返回值的相关说明。

使用go doc查看文档

使用go doc工具可以查看包相关的注释文档:

❯ go doc input
package input // import "github.com/icexmoon/go-notebook/ch11/input"
​
Package input read string from keyboard
​
func GetLine() (string, error)

根据注释自动生成的文档信息中,最开头是包名及导入路径,下边是包的解释信息,此外还会包含包中的函数。

可以进一步查看某个函数的相关文档:

❯ go doc input.GetLine
package input // import "github.com/icexmoon/go-notebook/ch11/input"
​
func GetLine() (string, error)
    GetLine will read a line from keyboard and return

通过go doc不仅可以查看自己编写的文档,实际上可以查看所有标准库以及下载的第三方包的文档:

❯ go doc bufio
package bufio // import "bufio"
​
Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer
object, creating another object (Reader or Writer) that also implements the
interface but provides buffering and some help for textual I/O.
...

使用浏览器查看文档

使用godoc工具可以通过浏览器查看注释文档,这点在Go语言编程笔记1:Hello World中已经有过说明,就不再重复。

谢谢阅读。

往期内容

  • Go语言编程笔记10:使用共享变量实现并发(续)

  • Go语言编程笔记9:使用共享变量实现并发

  • Go语言编程笔记8:goroutine续

  • Go语言编程笔记7:goroutine和通道

  • Go语言编程笔记6:接口

  • Go语言编程笔记5:函数

  • Go语言编程笔记4:结构体和切片

  • Go语言编程笔记3:控制流

  • Go语言编程笔记2:变量

  • Go语言编程笔记1:Hello World

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2021年11月28日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号