教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 如何编写Go代码

如何编写Go代码

发布时间:2022-03-23   编辑:jiaochengji.com
教程集为您提供如何编写Go代码等资源,欢迎您收藏本站,我们将为您提供最新的如何编写Go代码资源
<h2>简介</h2>

本文演示了一个简单的Go语言包的开发,以及 <code>go tool</code> 命令的使用,包含:获取、构建、安装Go包和命令的标准方法。

<code>go tool</code> 要求用特别的方式来组织你的Go代码。仔细阅读本文,它解释了启动和运行Go安装的最简单方法。

<h2>代码组织</h2><h3>概述</h3><ul><li>程序员通常会将所有Go代码保存在一个工作区中</li><li>工作空间包含许多版本控制的仓库(repo)(例如,由Git管理的)</li><li>每个仓库包含一个或多个包</li><li>每个包由一个目录中的一个或多个Go源文件组成</li><li>包目录的路径确定其导入路径</li></ul>

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

<h3>工作区</h3>

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

<ul><li><code>src</code> 用于存放Go原文件</li><li><code>bin</code> 存放可执行的命令</li></ul>

go工具构建二进制文件并将其安装到 <code>bin</code> 目录。

<code>src</code> 子目录通常包含多个版本控制的仓库(例如Git),用于跟踪一个或多个源包的开发。

在实践中,工作区应该是什么样子呢? 下面给出一个例子:

<pre><code>bin/ hello # command executable outyet # command executable src/ 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) ... </code></pre>

上面的这个树型结构展示出一个工作区包含了2个仓库(<code>example</code> 和 <code>image</code>)。<code>example</code> 仓库包含了2个命令(<code>hello</code> 和 <code>outyet</code>)和一个库(<code>stringutil</code>)。<code>image</code> 仓库包含了 <code>bmp</code> 包和 一些其他的包。

通常工作区会包含很多的源仓库(包含需要多和命令)。大多数的Go开发者都会把他们的源代码和依赖存放在一个工作区。

命令和库是从不同类型的源包构建的。我们稍后会讨论这种区别。

<h3>GOPATH 环境变量</h3>

<code>GOPATH</code> 环境变量用来指定工作区的位置。默认是用户主目录的 <code>go</code> 目录,如在Linux和macOS上是 <code>$HOME/go</code>, 在Windows上是 <code>C:\Users\YourName\go</code>。

<code>go env GOPATH</code> 命令会打印出当前有效的 <code>GOPATH</code>; 如果环境变量没有被设置会打印出默认的位置。

为方便起见,将工作空间的 <code>bin</code> 子目录添加到 <code>PATH</code>:

<pre><code>$ export PATH=$PATH:$(go env GOPATH)/bin</code></pre>

为简洁起见,本文档其余部分中的脚本使用 <code>$GOPATH</code> 而不是 <code>$(go env GOPATH)</code>。即

<pre><code>$ export PATH=$PATH:$GOPATH/bin</code></pre>

而如果还没有设置 <code>$GOPATH</code> 就运行写好的脚本,你需要替换为 <code>$HOME/go</code>, 否则需要执行:

<pre><code>$ export GOPATH=$(go env GOPATH)</code></pre>

要学习更多关于gopath环境变量,可以使用查看帮助 <code>go help gopath</code>

要使用自定义的工作区,可以查看 https://golang.org/wiki/SettingGOPATH

<h3>导入路径</h3>

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

标准库中的包具有简短的导入路径,例如 <code>fmt</code> 和 <code>net/http</code>。对于我们自己开发的包您必须选择一个基本路径,该路径不太可能与将来添加到标准库或其他外部库中发生冲突。

如果将代码保存在某个源仓库中,则应使用该源仓库的根作为基本路径。例如,如果你在 <code>github.com/user</code> 上有一个GitHub帐户,那么这应该是你的基本路径。

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

我们将使用 <code>github.com/user</code> 作为我们的基本路径。在工作区内创建一个目录,用于保存源代码:

<pre><code>$ mkdir -p $GOPATH/src/github.com/user</code></pre><h3>你的第一个Go程序</h3>

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

<pre><code>$ mkdir $GOPATH/src/github.com/user/hello</code></pre>

接下来,在hello目录里创建一个 <code>hello.go</code> 文件,写入以下内容:

<pre><code>package main import "fmt" func main() { fmt.Println("Hello, world.") }</code></pre>

现在就可以使用go工具来构建和安装该程序:

<pre><code>go install github.com/user/hello</code></pre>

注意,你可以在系统上的任何地方运行该命令。go工具通过在 <code>GOPATH</code> 指定的工作空间内查找 <code>github.com/user/hello</code> 包来查找源代码。

如果是在这个包目录内运行 <code>go install</code> 也可以忽略包路径:

<pre><code>$ cd $GOPATH/src/github.com/user/hello $ go install</code></pre>

该命令会生成一个 <code>hello</code> 命令,生成一个可执行的二进制文件。同时安装到工作区目录下的 <code>bin</code> 目录,生成的可执行文件是 <code>hello</code>(如果是windows则是 hello.exe)。
在本例子中是 <code>$GOPATH/bin/hello</code>, 也就是 <code>$HOME/go/bin/hello</code>。

当有错误发生的时候,go工具仅会打印除错误,所以如果没有任何输出的时候说明已经执行成功。

可以通过全路径来运行:

<pre><code>$ $GOPATH/bin/hello Hello, world.</code></pre>

如果已经把 <code>$GOPATH/bin</code> 加入到了 <code>PATH</code>, 可以直接输入二进制文件名:

<pre><code>$ hello Hello, world.</code></pre>

如果你正在使用一个版本控制系统,比如Git,现在是时候来初始化来生成一个仓库(repository),然后添加文件,做第一次提交。

<blockquote>当然这一步是可选的,不一定非要使用版本控制系统来写Go代码</blockquote><pre><code>$ cd $GOPATH/src/github.com/user/hello $ git init Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/ $ git add hello.go $ git commit -m "initial commit" [master (root-commit) 0b4507d] initial commit 1 file changed, 1 insertion( ) create mode 100644 hello.go $ git push origin master </code></pre><h3>你的第一个库</h3>

我们再来写一个库,并在 <code>hello</code> 程序中使用。

首先,第一步确定好包路径,我们使用 <code>github.com/user/stringutil</code>, 创建包目录

<pre><code>$ mkdir $GOPATH/src/github.com/user/stringutil</code></pre>

其次,创建一个名为 <code>reverse.go</code> 的文件,并写入以下内容:

<pre><code>// 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) }</code></pre>

使用 <code>go build</code> 编译该包:

<pre><code>$ go build github.com/user/stringutil</code></pre>

如果已经在 <code>github.com/user/stringutil</code> 目录里,则直接执行:

<pre><code>$ go build</code></pre>

当然该命令不会生成文件,而是把编译好的包放到了本地的构建(build)缓存里。
确实 <code>stringutil</code> 包被编译后, 修改 <code>hello.go</code>:

<pre><code>vim $GOPATH/src/github.com/user/hello</code></pre>

修改后的:

<pre><code>package main import ( "fmt" "github.com/user/stringutil" ) func main() { fmt.Println(stringutil.Reverse("!oG ,olleH")) }</code></pre>

再次安装

<pre><code>$ go install github.com/user/hello</code></pre>

执行:

<pre><code>$ hello Hello, Go!</code></pre>

通过上面的一些步骤后,现在我们的结构是这样子的:

<pre><code>bin/ hello # command executable src/ github.com/user/ hello/ hello.go # command source stringutil/ reverse.go # package source</code></pre><h3>包名</h3>

在Go原文件中第一个使用的语句必须是

<pre><code>package name</code></pre>

其中 <code>name</code> 就是包的默认名称。一个包中的所有文件必须使用相同的包名。

Go的约定是包名称是导入路径的最后一个元素,例如导入的包 <code>crypto/rot13</code>, 包名就是 <code>rot13</code>

如果是可执行的文件,包名必须使用 <code>main</code>。

不强制要求所有的包名都是唯一的,但是要求导入的路径必须是唯一的(全路径文件名)。

更多关于go的命名规范可以查看 Effective Go

<h2>测试</h2>

Go提供了一个由 <code>go test</code> 和 <code>testing</code> 包组成的测试框架。

通过创建一个以 <code>_test.go</code> 结尾的文件,里面写有以 <code>TestXXX</code> 开头的函数。测试框架会运行每一个这样的函数,如果函数调用了一个失败的函数,如 <code>t.Error</code> 或 <code>t.Error</code>, 那么测试就算不通过。

通过添加一个测试文件到 <code>stringutil</code> 包中,

<pre><code>$ vim $GOPATH/src/github.com/user/stringutil/reverse_test.go</code></pre>

添加如下代码:

<pre><code>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) } } }</code></pre>

然后运行测试 <code>go test</code>:

<pre><code>$ go test github.com/user/stringutil ok github.com/user/stringutil 0.165s</code></pre>

如果当前是在 <code>go test github.com/user/stringutil</code> 目录中,则直接执行:

<pre><code>$ go test ok github.com/user/stringutil 0.165s</code></pre>

更多细节可以运行 go run test 和 查看 测试包文档

<h2>远程包</h2>

导入路径可以描述如何使用诸如Git之类的版本控制系统来获取包源代码。go工具使用此属性自动从远程仓库获取包。例如,本文档中描述的示例也保存在GitHub <code>github.com/golang/example</code> 上托管的Git仓库中。如果你在包的导入路径中包含仓库URL,那么go将自动获取,构建和安装它:

<pre><code>$ go get github.com/golang/example/hello $ $GOPATH/bin/hello Hello, Go examples!</code></pre>

如果指定的包不在工作区, <code>go get</code> 将会通过 <code>GOPATH</code> 把它放到指定的工作区,如果包已经存在, <code>go get</code> 会跳过远程获取,其行为与 <code>go install</code> 相同。

上面 <code>go get</code> 之后的目录结构如下:

<pre><code>bin/ hello # command executable src/ 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</code></pre>

在GitHub上托管的 <code>hello</code> 命令取决于同一仓库中的 <code>stringutil</code> 包。 <code>hello.go</code> 文件中的导入使用相同的导入路径约定,因此 <code>go get</code> 命令也能够找到并安装依赖包。

<pre><code>import "github.com/golang/example/stringutil"</code></pre>

此约定是使你的Go包可供其他人使用的最简单方法。

Go Wiki和godoc.org提供了外部Go项目的列表。

有关使用go工具使用远程仓库的更多信息, 可以查看 go help importpath

<blockquote>原文地址:https://phpcasts.org/topics/47</blockquote> 到此这篇关于“如何编写Go代码”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
想系统学习GO语言(Golang
go语言和python哪个难
go run main.go 参数_Go语言入门:Hello world
龙芯平台构建Go语言环境指南
Go语言爱好者周刊:第 78 期 — 这道关于 goroutine 的题
go 语言学习历程
Golang基础入门01 | 简介
Go 语言学习第一章节
Go 开发关键技术指南 | 为什么你要选择 Go?(内含超全知识大图)
go html提取纯文本_Go 语言高性能编程

[关闭]
~ ~