本文会演示简单的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 的工作区大概的样子:

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

$ export PATH=$PATH:$(go env GOPATH)/bin

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

$ export GOPATH=$(go env GOPATH)

包的导入路径

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

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

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

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

$ mkdir -p $GOPATH/src/github.com/user

你的第一个Go程序

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

$ mkdir $GOPATH/src/github.com/user/hello

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

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

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

$ go install github.com/user/hello

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

$ cd $GOPATH/src/github.com/user/hello
$ go install

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

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

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

$ $GOPATH/bin/hello
Hello, world.

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

$ hello
Hello, world.

你的第一个 library

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

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

$ mkdir $GOPATH/src/github.com/user/stringutil

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

// 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测试软件包的编译情况:

$ go build github.com/user/stringutil

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

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

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

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

$ hello
Hello, Go!

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

bin/hello
src/github.com/user/hello/hello.gostringutil/reverse.go

包名

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

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包。

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/stringutil
ok      github.com/user/stringutil 0.165s

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

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

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

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

bin/hello
src/github.com/golang/example/.git/                      hello/hello.gostringutil/reverse.goreverse_test.go         github.com/user/hello/hello.go                 stringutil/reverse.go               reverse_test.go         

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

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 代码的技巧。

如何正确的开始用Go编程相关推荐

  1. 学java的正确方法_学习Java编程 这10个技巧不容错过--中享思途

    这是一个国外大神20多年的经验总结出来的-- "任何可能出错的事情,最后都会出错." 这就是人们为什么喜欢进行"防错性程序设计"的原因.偏执的习惯有时很有意义, ...

  2. 如何正确的开始用 Go 编程

    本文会演示简单的Go软件包的开发过程,并介绍了go命令行工具,这是我们获取,构建和安装Go软件包和命令的标准方法. go工具要求你以特定方式组织代码.我们会介绍Go安装启动和运行的最简单方法,一定要仔 ...

  3. go get 的不再src目录中_如何正确的开始用Go编程

    本文会演示简单的Go软件包的开发过程,并介绍了 go命令行工具,这是我们获取,构建和安装Go软件包和命令的标准方法. go工具要求你以特定方式组织代码.我们会介绍Go安装启动和运行的最简单方法,一定要 ...

  4. python并发编程方法_Python Futures并发编程详解

    无论哪门编程语言,并发编程都是一项很常用很重要的技巧.例如,爬虫就被广泛应用在工业界的各个领域,我们每天在各个网站.各个 App 上获取的新闻信息,很大一部分便是通过并发编程版的爬虫获得. 正确合理地 ...

  5. 【连载】Scala程序设计:Java虚拟机多核编程实战——简介

    可以在JVM上编程的语言有很多.通过这本书,我希望让你相信花时间学习Scala是值得的. Scala语言为并发.表达性和可扩展性而设计.这门语言及其程序库可以让你专注于问题领域,而无需深陷于诸如线程和 ...

  6. java程序设计试题_《Java语言程序设计》期末考试模拟试题——填空题和编程题...

    一.根据题意,填写出空格中的内容 Java平台包括三个技术方向,其中J2ME代表____________.J2SE代表___________.J2EE代表____________.2.面向对象的四大概 ...

  7. asyncio并发数_Python Futures并发编程详解

    无论哪门编程语言,并发编程都是一项很常用很重要的技巧.例如,爬虫就被广泛应用在工业界的各个领域,我们每天在各个网站.各个 App 上获取的新闻信息,很大一部分便是通过并发编程版的爬虫获得.正确合理地使 ...

  8. c++数据结构代码整理_抄代码对自己编程提高有用嘛

    仅作学术分享,不代表本公众号立场,侵权联系删除 知乎链接:https://www.zhihu.com/question/387940895编辑:深度学习与计算机视觉 自己刚接触数据结构,完成大作业感觉 ...

  9. 编程开发使用的辅助软件大全

    (今天太晚了,以后再慢慢写) 说明: 本文提及的所有软件都至少是笔者曾经使用过的,而不是阅自其它文献. 对于其中的某些软件,笔者也编写过其完整的安装教程,可阅读笔者编写的其它博客. 本文只是给出编程人 ...

最新文章

  1. python打包成exe_【Python】使用pyinstaller打包成exe文件时可以显示图片的方法
  2. sqlserver 班级排名_Sqlserver:班级排名问题(转发)
  3. Hive创表异常,FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask.
  4. linux 笔记--系统启动流程
  5. windows 文件对话框
  6. 单实例数据库和多实例数据库
  7. 4G模组工作笔记001---NB-IOT之一个完整的BC95 UDP从开机到数据发送接收过程
  8. 智能车学习(一)—— 硬件准备
  9. 微信,QQ抢红包软件原理解析
  10. Java版2048小游戏
  11. 计算机指令窗口如何放大,我电脑每次打开一个窗口都好小,怎么设置为每次都全屏啊?...
  12. 三种常用的数字数据编码方式
  13. 计算机弹音乐薛之谦的歌曲,薛之谦 万能音符(The Key) 薛之谦歌曲,薛之谦mp3在线试听 - 5nd音乐网...
  14. 科普:蓝绿部署、金丝雀发布(灰度发布)、A/B测试
  15. 一台电脑同时安装IE6、IE7、IE8三种浏览器
  16. JSP——猜英文小写字母的Web小游戏
  17. statgraphics画Multifactor ANOVA图
  18. oracle用升序索引去降序查询,Oracle工作札记
  19. phpmailer报 You must provide at least one recipient email address.解决办法
  20. 小技巧:unicode RLO

热门文章

  1. SIM800C Couldn't pair with xxx because of an incorrect PIN or passkey
  2. centos 字体的修改
  3. JAVA Swing 事件监听
  4. 如何修改WAMP中mysql默认空密码重新登录phpmyadmin
  5. 五大常用算法:分治、动态规划、贪心、回溯、分支限界
  6. 打造数据中心的软实力
  7. 字符验证码识别项目记录
  8. 更改数据库的兼容模式
  9. JavaScript依赖注入的实现思路
  10. python3的文件读写模式