前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何正确的开始用Go编程

如何正确的开始用Go编程

作者头像
KevinYan
发布2020-01-14 15:49:17
4930
发布2020-01-14 15:49:17
举报
文章被收录于专栏:网管叨bi叨网管叨bi叨

本文会演示简单的Go软件包的开发过程,并介绍了 go命令行工具,这是我们获取,构建和安装Go软件包和命令的标准方法。

go工具要求你以特定方式组织代码。我们会介绍Go安装启动和运行的最简单方法,一定要仔细阅读啊。

组织代码结构

概要

  • Go 程序员一般会将他们的源代码存放在一个工作区中(多个项目放在一个工作区)
  • 工作区中包含许多由 git 管理的代码仓库(也可以是其他版本控制工具管理的)
  • 每个代码仓库包含一个或者多个 Go package
  • 每个 package 由单一目录下的一个或多个Go 源码文件组成
  • package 的目录路径决定了其导入路径

与其他编程语言不同的是,在其他编程语言里每个项目都有自己的工作区,并且工作区都与版本控制系统紧密相关。

工作区

工作区是一个目录层级,这个目录层级在顶层有两个目录:

  1. src 目录,存放源代码文件。
  2. bin 目录,存放可执行二进制文件。

go命令工具会把 src中的Go 文件构建生成二进制文件放在 bin目录中。

src子目录通常包含用 git 管理的多个代码仓库,他们对应一个或多个Go 包的开发源码。

一个典型的工作区中会包含多个源码仓库,对应多个可执行命令源码和包源码。大多数 Go 程序员会把他们的Go 源码和所有依赖的包都放在单一的工作区中。

下面的例子可以让你更好的了解Go 的工作区大概的样子:

代码语言:javascript
复制
bin/
    hello                          # 可执行命令文件
    outyet                         # 可执行命令文件
src/
    github.com/golang/example/
        .git/                      
        hello/
              hello.go               # 命令文件源码
        outyet/
              main.go                # 命令文件源码
              main_test.go           # 测试文件
        stringutil/
              reverse.go             # package源码
              reverse_test.go        # 测试文件
    golang.org/x/image/
        .git/               
        bmp/
            reader.go              # package 源码
            writer.go              # package 源码
  ......

上面的目录树展示了工作区中的两个代码仓库(example 和 image)。example 仓库中包含两个命令hello 和 outyet(hello 和 outyet 目录中存放的就是两个命令的源码)一个被用作库的 package - stirngutil 。image仓库中包含一个 bmp包。

注意:不能使用符号链接(软链 ln -s)将文件链接到工作区中。

执行命令和库是从不同类的源码包构建出来的,这个之后的部分会进行说明。

GOPATH 环境变量

GOPATH环境变量指定工作区的位置。它缺省为用户目录中名为go的目录,因此在Linux上为 $HOME/go,在Windows上通常为 C:\Users\YourName\Go

如果想在其他位置放置工作区,则需要将 GOPATH设置为该目录的路径。请注意,GOPATH不得与GO安装路径相同。

命令 go env GOPATH打印当前有效的 GOPATH;如果环境变量未设置,它将打印默认位置。为方便起见,可以请将工作区的 bin子目录添加到系统环境变量 $PATH

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

同时也把 GOPATH设置成系统的环境变量:

代码语言:javascript
复制
$ export GOPATH=$(go env GOPATH)

包的导入路径

一个导入路径是用来唯一标识包的字符串,包的导入路径和他在工作区中的位置相对应。标准库中的包具有较短的导入路径,如“fmt”和“net/http”。对于您自己的软件包,你必须选择一个不太可能与将来添加到标准库或其他外部库中的内容冲突的基本路径。

如果你将代码保存在某个源代码库中,那么应该使用该源代码库的根目录作为你的基本路径。例如,如果你在github.com上有一个GitHub帐户user,你创建的仓库都会以 github.com/user 为前缀,那么 github.com/user这应该是你的基本路径。

请注意,在构建代码之前,你不需要将代码发布到远程存储库。就像有一天会发布代码一样来组织代码,这是一个好习惯。实际上,您可以选择任意路径名,只要它是唯一的。

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

代码语言:javascript
复制
$ mkdir -p $GOPATH/src/github.com/user

你的第一个Go程序

要编译并运行一个简单的程序,首先选择一个软件包路径(我们将使用github.com/user/hello),并在您的工作区内创建一个相应的软件包目录:

代码语言:javascript
复制
$ mkdir $GOPATH/src/github.com/user/hello

接下来,在该目录中创建一个名为hello.go的文件,添加以下代码:

代码语言:javascript
复制
package main

import "fmt"

func main() {
    fmt.Println("Hello, world.")
}

现在,你可以使用go工具构建和安装该程序了:

代码语言:javascript
复制
$ go install github.com/user/hello

你可以从系统上的任何位置运行此命令。go命令工具通过在 GOPATH指定的工作区内查找 github.com/user/hello包来查找源代码。如果从软件包目录运行 goInstall,可以省略软件包路径:

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

go install构建hello命令,生成一个可执行的二进制文件。然后,它将该二进制文件作为hello(在Windows下为hello.exe)安装到工作区的bin目录中,hello 可执行命令的位置为 $GOPATH/bin/hello

Go工具仅在发生错误时打印输出,因此如果这些命令没有产生输出,则代表它们已成功执行。

现在,你可以通过在命令行中键入程序的完整路径来运行该程序:

代码语言:javascript
复制
$ $GOPATH/bin/hello
Hello, world.

由于您已将 $GOPATH/bin添加到路径中,因此只需键入二进制文件的名字:

代码语言:javascript
复制
$ hello
Hello, world.

你的第一个 library

让我们编写一个库并在上面写的hello程序中使用它。

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

代码语言:javascript
复制
$ mkdir $GOPATH/src/github.com/user/stringutil

接下来在目录中创建 reverse.go文件并添加如下代码:

代码语言:javascript
复制
// stringutil包 存放关于字符串的工具函数
package stringutil

// Reverse 将参数中的字符串反转后的字符串
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测试软件包的编译情况:

代码语言:javascript
复制
$ go build github.com/user/stringutil

go build不会产生输出文件。相反,它将编译后的包保存在本地构建缓存中。

在确认 stringutil包构建可以正确之后,修改原始的 hello.go(位于$GOPATH/src/github.com/user/hello中)以使用它:

代码语言:javascript
复制
package main

import (
    "fmt"

    "github.com/user/stringutil"
)

func main() {
    fmt.Println(stringutil.Reverse("!oG ,olleH"))
}

再次编译安装 hello 程序后运行他,可以看到输出中的字符串已经被反转了。

代码语言:javascript
复制
$ hello
Hello, Go!

经过上面几步后你的工作区现在应该看起来像下面这样:

代码语言:javascript
复制
bin/
    hello
src/
    github.com/user/
        hello/
            hello.go
        stringutil/
            reverse.go

包名

go 源码文件中的第一行语句必须是:

代码语言:javascript
复制
package name

其中,name是用于导入的包的默认名称。(包中的所有文件必须使用相同的名称)

go的惯例是包名是导入路径的最后一个元素:作为“crypto/rot13”导入的包它的包名为 rot13

生成可执行命令的源码文件必须以 main作为包名。

go 中不要求链接到单个二进制文件的所有包的包名都是唯一的,只要求导入路径(它们的完整文件名)是唯一的。

测试

go有一个由go测试命令和测试包组成的轻量级测试框架。你可以通过创建一个名字以 _test.go结尾的文件来编写测试,该文件包含名为TestXXX的函数,签名函数为 func(t*testing.T)。测试框架运行每个这样的函数;如果函数调用失败函数,如t.Error或t.Fail,则认为测试失败。

通过创建包含以下go代码的文件 $GOPATH/src/github.com/user/stringutil/reverse_test.go,将测试添加到 strangutil包。

代码语言:javascript
复制
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运行测试

代码语言:javascript
复制
$ go test github.com/user/stringutil
ok      github.com/user/stringutil 0.165s

导入路径可以描述如何从版本控制系统(如Git)获取包源代码。Go工具使用此属性自动从远程仓库中获取包。例如,本文档中描述的示例也保存在GitHub 以github.com/golang/example托管的Git存储库中。如果将代码仓库的URL包含在软件包的导入路径中,go将会使用go get`自动获取、构建和安装它:

代码语言:javascript
复制
$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!

如果工作区中没有指定的包, goget将把它放在 $GOPATH指定的工作区中。(如果软件包已经存在, goget将跳过远程获取,其行为变得与 go install相同。)。

发出上述 goget命令后,工作区目录树现在应该如下所示:

代码语言:javascript
复制
bin/
    hello
src/
    github.com/golang/example/
        .git/                      
        hello/
            hello.go
        stringutil/
            reverse.go
            reverse_test.go         
    github.com/user/
        hello/
            hello.go                 
        stringutil/
            reverse.go               
            reverse_test.go

托管在GitHub上的hello命令依赖于同一仓库中的 stringutil包。hello.go文件中的导入使用相同的导入路径约定,因此 goget命令也能够定位和安装依赖包。

代码语言:javascript
复制
import "github.com/golang/example/stringutil"

What's Next

  • 《Go语言之旅》https://tour.go-zh.org/list 了解 Go 语言的基础语法
  • 《Go 入门指南》https://learnku.com/docs/the-way-to-go 通过了200 多个完整的代码示例和书中的解释说明来对所有涉及到的概念和技巧进行彻底的讲解。
  • 《Go语言程序设计》https://yar999.gitbooks.io/gopl-zh/content/ 通过学习这本书会对 Go 有更全面的认识,强化自己的Go语言底层基础知识。
  • 《Effective Go 中文版》https://learnku.com/docs/effective-go/2020 提供编写清晰高效、地道的 Go 代码的技巧。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网管叨bi叨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 组织代码结构
    • 概要
      • 工作区
        • GOPATH 环境变量
          • 包的导入路径
            • 你的第一个Go程序
              • 你的第一个 library
                • 包名
                  • 测试
                    • What's Next
                    相关产品与服务
                    命令行工具
                    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档