如何正确的开始用 Go 编程

如何正确的开始用 Go 编程

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

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

组织代码结构

概要

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

与其余编程语言不一样的是,在其余编程语言里每一个项目都有本身的工做区,而且工做区都与版本控制系统紧密相关。github

工做区

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

  1. src 目录,存放源代码文件。shell

  2. bin 目录,存放可执行二进制文件。编程

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

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

一个典型的工做区中会包含多个源码仓库,对应多个可执行命令源码和包源码。大多数 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包来查找源代码。若是从软件包目录运行go Install,能够省略软件包路径:

$ 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.go      
        stringutil/
            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!
复制代码

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

发出上述go get命令后,工做区目录树如今应该以下所示:

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文件中的导入使用相同的导入路径约定,所以go get命令也可以定位和安装依赖包。

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

What's Next

  • 《Go语言之旅》tour.go-zh.org/list 了解 Go 语言的基础语法
  • 《Go 入门指南》learnku.com/docs/the-wa… 经过了200 多个完整的代码示例和书中的解释说明来对全部涉及到的概念和技巧进行完全的讲解。
  • 《Go语言程序设计》yar999.gitbooks.io/gopl-zh/con… 经过学习这本书会对 Go 有更全面的认识,强化本身的Go语言底层基础知识。
  • 《Effective Go 中文版》learnku.com/docs/effect… 提供编写清晰高效、地道的 Go 代码的技巧。

WX20191117-152623@2x.png
相关文章
相关标签/搜索