写点什么

【译】如何编写 Go 代码(使用 GOPATH)

用户头像
xcbeyond
关注
发布于: 2021 年 04 月 07 日

1、介绍

如果您不熟悉 Go 语言,请参阅最新的 How to Write Go Code


本文档演示了一个简单的 Go 包的开发过程,并介绍了go命令,可从这是获取构建和安装命令的方法。


go命令要求您以特定方式组织代码。请仔细阅读本文档。它说明了 Go 安装启动和运行的最简单方法。


在这里 也提供了类似的说明 。

2、代码组织

2.1 概述

  • Go 程序员通常将所有 Go 代码保存在一个工作空间 workspace 中。

  • 工作空间中包含多个版本控制仓库(如,由 Git 管理)。

  • 每个仓库包含一个或多个包。

  • 每个包都在一个目录中包含一个或多个 Go 源文件。

  • 包目录的路径确定其导入路径。


请注意,这与其他编程环境不同,在其他编程环境中,每个项目都有一个单独的工作空间,并且这些工作空间与版本控制仓库紧密相关。

2.2 工作空间

工作空间是一个目录层次结构,其根目录下有两个目录:


  • src: 包含 Go 源文件

  • bin :包含可执行命令。


go工具将生成的二进制文件存放到到 bin 目录中。


src 子目录通常包含一个或多个源代码包的版本控制仓库(例如,Git)。


为了让您大致了解工作空间,下面有一个示例:


bin/    hello                          # command executable    outyet                         # command executablesrc/    github.com/golang/example/        .git/                      # Git repository metadata  hello/      hello.go               # command source  outyet/      main.go                # command source      main_test.go           # test source  stringutil/      reverse.go             # package source      reverse_test.go        # test source    golang.org/x/image/        .git/                      # Git repository metadata  bmp/      reader.go              # package source      writer.go              # package source    ... (many more repositories and packages omitted) ...
复制代码


上面的树结构显示了包含两个仓库(exampleimage)的工作空间。example仓库包含两个命令(hellooutyet)和一个库(stringutil)。image仓库包含bmp包和其他包


一个典型的工作空间会包含许多源代码仓库,这些源代码仓库包含许多包和命令。大多数 Go 程序员将所有 Go 源代码和依赖包都保存在一个工作空间中。


命令和库是从不同种类的源包中构建的,我们将会在后面讨论。

2.3 GOPATH 环境变量

GOPATH 环境变量是指你工作空间的目录。默认情况下,该目录位于您用户目录内的 go 文件夹,在 Unix 环境是$HOME/go,在 Windows 环境是 C:\Users\YourName\go


如果您想设置其它目录,则需要将其设置为 GOPATH。(另一种常见的设置方法是set GOPATH=$HOME。)


通过命令go env GOPATH 可以查看当前设置的 GOPATH。如果未设置环境变量,它将显示默认位置。


如果您想在其他位置工作,则需要将其 设置GOPATH 为该目录的路径。(另一种常见的设置是设置GOPATH=$HOME。)请注意,GOPATH一定不能像你去安装相同的路径。


该命令go env GOPATH 打印有效电流GOPATH; 如果未设置环境变量,它将打印默认位置。


为了方便起见,需将工作空间的bin 目录添加到您的PATH中:


export PATH=$PATH:$(go env GOPATH)/bin
复制代码


本文涉及的脚本中,为了方便,使用 $GOPATH 来替代$(go env GOPATH)。要是在未设置 GOPATH的情况下,可替换为$HOME/go,或运行下面命令:


$ export GOPATH=$(go env GOPATH)
复制代码


想要了解有关GOPATH环境变量的更多信息,请参见 go help gopath

2.4 导入路径

import path是唯一标识一个包的字符串。包的导入路径是与其在工作空间内或在远程仓库中的位置相对应(如下所述)。


标准库中的包具有简短的导入路径,例如 "fmt""net/http"。对于您自己的包,您必须选择一个根路径,确保该根路径将来不会与标准库或其他外部库中的内容冲突。


如果将代码保存在源代码仓库的某个位置,则应使用该源代码仓库的根作为根路径。例如,如果您拥有 GitHub 帐户 github.com/user,则其应为您的根路径。


请注意,在构建代码之前,无需将代码发布到远程仓库。这是组织代码的好习惯,就像您一天要发布代码一样。实际上,您可以选择任意路径名,只要它对标准库和更大的 Go 生态系统是唯一的即可。


我们将使用github.com/user作为我们的根路径。在工作空间内创建一个目录,保存源代码:


$ mkdir -p $GOPATH/src/github.com/user
复制代码

2.5 您的第一个程序

要编译并运行一个简单程序,首先选择一个包路径(我们使用 github.com/user/hello),然后在工作空间中创建一个相应的包目录:


$ mkdir $GOPATH/src/github.com/user/hello
复制代码


接下来,在该目录内创建一个文件hello.go,Go 代码如下:


package main
import "fmt"
func main() { fmt.Println("Hello, world.")}
复制代码


现在,您可以使用go 命令来构建和安装该程序:


$ go install github.com/user/hello
复制代码


请注意,您可以从系统上的任何位置运行此命令,该 go 命令通过github.com/user/hello所指定的工作空间中查找包。


如果go install命令在包目录运行,可以省略包路径:


$ cd $GOPATH/src/github.com/user/hello$ go install
复制代码


该命令编译生成可执行的二进制文件hello(Window 环境是 hello.exe 文件),然后将该二进制文件安装到工作空间的 bin目录中。在我们的示例中,存放到$GOPATH/bin/hello,即 $HOME/go/bin/hello


当发生错误时,go install 命令会输出错误信息,否则表示成功执行。


现在,您可以通过在命令行中输入其完整路径来运行该程序:


$ $GOPATH/bin/helloHello, world.
复制代码


或者,如果您将$GOPATH/bin添加到环境变量 PATH,只需输入二进制文件名称:


$ helloHello, world.
复制代码


如果您使用的是版本控制工具,下面是初始化仓库,添加文件并提交。同样,此步骤是可选的:您无需使用版本控制工具即可编写 Go 代码。


$ cd $GOPATH/src/github.com/user/hello$ git initInitialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/$ git add hello.go$ git commit -m "initial commit"[master (root-commit) 0b4507d] initial commit 1 file changed, 7 insertion(+) create mode 100644 hello.go
复制代码

2.6 您的第一个库

让我们编写一个库,让hello 程序使用它。


同样,第一步是选择一个包路径(我们使用 github.com/user/stringutil)并创建包目录:


$ mkdir $GOPATH/src/github.com/user/stringutil
复制代码


接下来,在该目录中创建reverse.go,代码如下:


// Package stringutil contains utility functions for working with strings.package stringutil
// Reverse returns its argument string reversed rune-wise left to right.func Reverse(s string) string { r := []rune(s) for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { r[i], r[j] = r[j], r[i] } return string(r)}
复制代码


使用go build 命令编译该包:


$ go build github.com/user/stringutil
复制代码


或者,在包目录下只需执行:


$ go build
复制代码


这不会产生输出文件,而是将已编译的包保存在本地缓存中。


确认stringutil 包可以生成后,修改hello.go


package main
import ( "fmt"
"github.com/user/stringutil")
func main() { fmt.Println(stringutil.Reverse("!oG ,olleH"))}
复制代码


安装hello程序:


$ go install github.com/user/hello
复制代码


运行新版本的程序,您应该看到一条新的逆向消息:


$ helloHello, Go!
复制代码


完成上述步骤后,工作空间目录结构如下:


bin/    hello                 # command executablesrc/    github.com/user/        hello/            hello.go      # command source        stringutil/            reverse.go    # package source
复制代码

2.7 包名

Go 源文件中的第一条语句必须为


package name
复制代码


导入默认的包名 name。(包中的所有文件都必须使用相同的包名name。)


Go 语言约定,包名称是导入路径的最后单词:以 crypto/rot13形式导入的包应命名为rot13


可执行命令的包必须使用 package main

3、测试

Go 具有由go test 命令和 testing 包组成的轻量级测试框架。


您可以通过创建一个名为_test.go结尾的文件来编写测试代码,该文件包含名为 TestXXX 的函数 func (t *testing.T) ,测试框架运行每一个这样的函数。如果函数调用失败函数,例如 t.Errort.Fail ,则测试被视为失败。


创建一个测试包stringutil, 测试源文件 $GOPATH/src/github.com/user/stringutil/reverse_test.go 如下:


package stringutil
import "testing"
func TestReverse(t *testing.T) { cases := []struct { in, want string }{ {"Hello, world", "dlrow ,olleH"}, {"Hello, 世界", "界世 ,olleH"}, {"", ""}, } for _, c := range cases { got := Reverse(c.in) if got != c.want { t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) } }}
复制代码


执行go test 命令:


$ go test github.com/user/stringutilok    github.com/user/stringutil 0.165s
复制代码


同样,在包目录下执行该命令,则可以省略包路径:


$ go testok    github.com/user/stringutil 0.165s
复制代码


执行go help test 命令,并查看 testing package documentation 以获取更多详细信息。

4、远程包

包导入路径可以描述如何使用修订控制系统(例如,GitMercurial)获取软件包源代码。使用go命令可以自动从远程仓库中拉取包。例如,本文档中描述的示例也保存在 GitHub 的仓库 github.com/golang/example 中。如果在包的导入路径中包含仓库 URL,则可通过 go get 命令自动获取、构建和安装:


$ go get github.com/golang/example/hello$ $GOPATH/bin/helloHello, Go examples!
复制代码


如果工作空间中不存在指定的包,go get 请将其放置在指定的第一个工作空间中GOPATH。(如果该软件包确实已经存在,则go get跳过远程获取并与行为相同go install。)


执行go get命令后,工作空间目录结构如下所示:


bin/    hello                           # command executablesrc/    github.com/golang/example/  .git/                       # Git repository metadata        hello/            hello.go                # command source        stringutil/            reverse.go              # package source            reverse_test.go         # test source    github.com/user/        hello/            hello.go                # command source        stringutil/            reverse.go              # package source            reverse_test.go         # test source
复制代码


helloGitHub上托管指令依赖于 stringutil同一档案库中包。在导入 hello.go文件中使用相同的导入路径约定,所以 go get命令能够找到并安装相关的包了。


import "github.com/golang/example/stringutil"
复制代码


此约定是使您的 Go 包可供其他人使用的最简单方法。 Pkg.go.devGo Wiki 提供了外部 Go 项目的列表。


有关通过go命令使用远程仓库的更多信息,请参见 go help importpath


原文:https://golang.org/doc/gopath_code

发布于: 2021 年 04 月 07 日阅读数: 18
用户头像

xcbeyond

关注

不为别的,只为技术沉淀、分享。 2019.06.20 加入

公众号:程序猿技术大咖,专注于技术输出、分享。

评论

发布
暂无评论
【译】如何编写Go代码(使用GOPATH)