Golang(一)开发环境

Golang编程语言是一个开源项目,它是一种表现力强、简洁、高效的语言。它的并发机制使得编写程序更容易从多核和网络化机器中获得最大收益,新类型系统实现了灵活的模块化程序构建。可以快速编译成机器代码,也具有便利的垃圾回收机制和运行时发射功能,作为一种快速、静态类型的编译语言,让人感觉像一种动态类型的解释语言。在深入Golang之前,首先要了解它的工作环境

Golang环境搭建

Golang发行版系统支持
官方二进制发行版可用于FreeBSD(Release 10-STABLE及更高版本)、Linux、MacOS(10.10及更高版本)、Windows操作系统以及32位(386)和64位(AMD64)x86处理器体系结构。go二进制发行版可用于这些受支持的操作系统和体系结构。在继续之前,请确保您的系统满足这些要求

golang supported

如果二进制发行版不适用于目标操作系统和体系结构的组合,请尝试从源安装或安装gccgo
以Go1.13.1为例进行安装介绍
安装包链接

// MicroSoft Windows(Windows7及更高版本)
https://dl.google.com/go/go1.13.1.windows-amd64.msi
// Apple MacOS (MacOS 10.11及更高版本)
https://dl.google.com/go/go1.13.1.darwin-amd64.pkg
// Linux (Linux 2.6.23及更高版本)
https://dl.google.com/go/go1.13.1.linux-amd64.tar.gz
// 源码
https://dl.google.com/go/go1.13.1.src.tar.gz

安装Go工具

// 对Linux、MacOS及FreeBSD系统,下载适当的tar文件,抽取文件到 /usr/local 目录,创建Go目录树 /usr/local/go(需要root权限)
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
// 设置环境变量
mkdir -p $HOME/workspace
vim $HOME/.bashrc
export GOPATH=$HOME/workspace
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
source $HOME/.bashrc
// WindowsOS 除了从源码安装之外,Go为Windows用户提供了两个安装选项:一个是zip归档文件,这需要配置一些环境变量;另一个是msi安装
// 通过zip文件解压到C盘,设置环境变量GOROOT及PATH

安装验证 通过简单程序验证Go是否正确安装,如下所示

// 新建project目录
mkdir -p $HOME/workspace/src/hello
cd $HOME/workspace/src/hello
// 编辑简单程序 hello.go
vim hello.go

package main

import "fmt"

func main() {
        fmt.Printf("hello, world\n")
}

 // 编译测试程序: 命令执行后将生成一个名为 hello的可执行文件
go build
// 执行 hello,显示`hello, world`,说明安装成功
./hello
 `hello, world`

// 安装到 workspace/bin
go install
// 从 workspace/bin 中移除 hello 命令
go clean -i

安装额外的Golang版本 在同一台机器上安装多个Go版本可能很有用,例如测试包需要通过多个Go版本。安装好一个版本后就可以安装另一个版本(例如 1.10.7),如下所示

go get golang.org/dl/go1.10.7
go1.10.7 download
// 新下载的版本使用方式
go1.10.7 version
`go version go1.10.7 linux/amd64`

卸载 从系统中删除现有go安装,只需删除go目录和环境变量即可

插件和IDE编辑器

Go社区提供了丰富的IDE支持来增强您的日常编辑、导航、测试和调试体验,例如

  • vim: vim-go 插件提供Go编程语言支持
  • Visual Studio Code: 为Go编程语言提供Go扩展支持
  • GoLand: GoLand 作为一个独立的IDE或IntelliJ IDEA Ultimate的插件发行
  • Atom: 来自GitHub的基于JavaScript的编辑器,它提供了 Go-Plus 支持
  • ...
file

如何编写Go代码

接下来以一个简单的示例介绍Go工具及获取、构建和安装Go包和命令的标准方法

代码组织
Go程序员通常将所有Go代码保存在一个workspace中

  • workspace可以包含许多版本控制库(例如git)

  • 每个repo包含一个或多个包

  • 每个包由单个目录中的一个或多个Go源文件组成

  • 包目录的路径决定了它的导入路径

    与其他编程环境不同,在这些环境中,每个项目都有一个单独的workspace,并且workspace与版本控制库密切相关

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

  • src 包含Go源文件。src子目录通常包含多个版本控制库(如git或mercurial),用于跟踪一个或多个源码包的开发

  • bin 包含可执行命令。go工具构建二进制文件并将其安装到bin目录

    以下示例展示workspace目录树的层级结构

bin/
hello # 可执行命令
outyet # 可执行命令
src/
github.com/golang/example/
.git/ # Git仓库元数据
hello/
hello.go # 命令源码
outyet/
main.go # 命令源码
main_test.go # 测试源代码
stringutil/
reverse.go # 包源代码
reverse_test.go # 测试包源代码
golang.org/x/image/
.git/ # Git仓库元数据
bmp/
reader.go # 包源代码
writer.go # 包源代码
... (更多repo及包在此处省略) ...

以上目录树展示了一个workspace包含两个repo: example和image。example库包含两个命令hello和outyet和一个库stringutil; image库包含bmp包和其他。一个典型的workspace包含许多包和命令的源码存储库,大多数Go程序员将所有Go源代码和依赖项保存在一个工作区中

Tips 不应使用符号链接将文件或目录链接到workspace中

GOPATH环境变量 gopath指定workspace的位置,默认为$HOME/go目录,如果你希望workspace指向其他位置,则需要将GOPATH设置为该目录的路径

tips GOPATH不能与go安装路径相同
export GOPATH=$HOME/SOMEDIR
命令打印有效的当前gopath;如果环境变量未设置,则打印默认位置
为了方便,将workspace的bin子目录添加到PATH中
export GOPATH=$(go env GOPATH)
export PATH=$PATH:$(go env GOPATH)/bin

Import paths 导入路径是唯一标识包的字符串。包的导入路径对应于其在workspace内或远程repo中的位置。标准库中的包被赋予短的导入路径,例如"fmt"和"net/http"; 对于您自己的包,您必须选择一个基本路径,该路径不太可能与将来添加到标准库或其他外部库的内容冲突
如果将代码保存在某个源码仓库中,则应使用该库的根作为基本路径。例如,如果您在github.com/user上有一个github帐户,那应该是您的基本路径

第一个程序 使用 github.com/user作为基本路径,在workspace内创建一个目录,用于保存源代码

mkdir -p $GOPATH/src/github.com/user
## 要编译和运行一个简单的程序,首先选择一个包路径(github.com/user/hello)并在workspace内创建一个相应的包目录
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工具通过在gopath指定的工作区内查找github.com/user/hello包来查找源代码
## 如果从包目录运行 go install,也可以省略包路径
cd $GOPATH/src/github.com/user/hello
## 这个命令编译hello.go生成可执行文件hello,然后安装hello(Windows中hello.exe)到workspace bin目录下($GOPATH/bin/hello)
go install

## 当错误发生时,go工具将会打印输出,如果命令没有产生输出,说明它已经执行成功
## 现在可以执行以下命令 $GOPATH/bin/hello 或 hello将产生以下输出
Hello, world.
## 如果您使用的是源代码管理系统,现在是初始化repo、添加文件和提交更改d的好时机;当然,这个步骤是可选的
cd $GOPATH/src/github.com/user/hello
git init
git add hello.go
git commit -m "initial commit"
git push -u origin

第一个库 编写一个库并从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

## 确认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"))
}

## install hello
go install github.com/user/hello

## 运行新版本的hello,将会看到输出反向字符串
hello
> Hello, Go!

# 完成这个步骤后,您的workspace目录树结构为
bin/
        hello                 # command executable
src/
        github.com/user/
                hello/
                        hello.go      # command source
                stringutil/
                        reverse.go    # package source

包名
## Go源文件中的第一个语句必须是,其中name是包导入的默认名称(包中的所有文件必须使用相同的包名)
package name

## go的约定是包名是导入路径的最后一个元素:作为“crypto/rot13”导入的包应命名为rot13
## 可执行命令必须始终使用 package main,没有要求包名称在链接到单个二进制文件的所有包中都是唯一的,只要求导入路径(它们的完整文件名)是唯一的

测试 Go有一个轻量级的测试框架,由go test命令和testing包组成。通过创建一个以_test.go结尾的文件来编写测试,该文件包含名为TestXXX的函数它的签名为func (t *testing.T),测试框架运行每一个这样的测试函数;如果测试函数调用一个失败函数,如t.Error或t.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/stringutil
> ok    github.com/user/stringutil 0.165s

Remote packages 导入路径可以描述如何使用修订控制系统(如git或mercurial)获取包源代码,Go工具使用此属性自动从远程存储库获取包。例如,本文中描述的示例也保存在github github.com/golang/example上的git仓库中。如果在包的导入路径中包含repo URL,则go get将自动获取、构建和安装它

go get github.com/golang/example/hello
$GOPATH/bin/hello

如果指定的包不在工作区中,go get会将其放在GOPATH指定的第一个workspace中(如果包已经存在,则go get跳过远程获取,其行为与go install相同)。在执行上面的go get命令之后,workspace目录树现在应该如下所示

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

托管在github上的hello命令依赖于同一repo中的stringutil包。hello.go文件中的导入使用相同的导入路径约定,因此go get命令也可以定位和安装依赖包

import "github.com/golang/example/stringutil"

小结

作为Golang系列文章的开篇,本文首先介绍Golang开发环境搭建,结合示例简单介绍go工具的使用方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容