开始编写GO

栏目: 编程工具 · 发布时间: 6年前

内容简介:注意这是和其他编程环境不同的地方:每个项目都有单独的工作空间,并且工作空间与版本控制仓库紧密绑定工作根目录有两个目录:

预览

  • Go程序员通常让所有的 Go 代码在一个单独的工作空间(workspace).
  • 一个工作空间包含很多版本控制仓库(比如,通过git管理)
  • 每个仓库包含一个或者多个包(packages).
  • 每个包由单独的目录下的Go源文件组成.
  • 包的目录路径决定他的 导入路径

注意这是和其他编程环境不同的地方:每个项目都有单独的工作空间,并且工作空间与版本控制仓库紧密绑定

工作空间

工作根目录有两个目录:

  • src 包含够源文件
  • bin 包含可执行命令

go tool 构建并安装binaries到 bin 目录

src 子目录一般包含多个版本控制仓库(比如Git或者Mercurial)追踪一个或多个源包的开发。

下面展示工作空间的结构:

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) ...</pre>

上面的树显示工作空间包含两个仓库( exampleimage )。 example 仓库包含两个命令( hellooutyet )和一把库( stringutil ). image 仓库包含 bmp 包和其他的一些内容

经典的工作空间包含多个源仓库,源仓库包含多个包和命令。大多数的Go程序员将所有的Go源代码和依赖放在一个单独的工作空间。

注意,不应该使用 symbolic links 关联文件或者目录到工作空间。

GOPATH环境变量

GOPATH环境变量指定工作空间的位置。默认是在home目录里的go目录,比如Unix的 $HOME/go ,Windows的 %USERPROFILE%\go (通常是 C:\Users\YourName\go )。

如果想在不同的地方,可以使用 set GOPATH 指定目录的路径。(另一种通用的设置是GOPATH=$HOME).注意GOPATH一定不能是Go的安装目录。

go env 命令打印当前有效的GOPATH,如果没有设置则打印默认的位置。

为了方便,添加工作空间的 bin 目录到你的路径:

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

为了简短,接下来的文档使用 开始编写GO (go env GOPATH)。

导入路径(Import paths)

import path 是唯一的字符串表示包。包的导入路径对应工作空间里它的位置或者远程仓库位置。

标准库里的包具有简短的导入路径,比如 fmtnet/http 。对于你自己的包,指定的路径不能与标准库里的包或者其他内部包冲突。

如果你将代码保存在源文件仓库,那么应该使用源仓库的根目录作为你的基础路径。比如,如果你有 Github 账号,那么 github.com/{user} 就是你的基本路径。

注意不要再你能构建之前推送代码到远程仓库。

我们将使用 github.com/{user} 作为你的基础路径。在工作空间下创建一个目录保存源代码:

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

第一个程序

要编译和运行一个简单的程序,先选择一个包路径(我们先用github.com/user/hello)并且在工作空间创建相应的包目录:

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

接下来,在这个目录下创建一个名为 hello.go 的文件,包含如下代码:

package main

import "fmt"

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

现在就可以构建并安装程序了:

$ go install github.com/user/hello

现在你就可以在你的系统里运行这个命令了。 go tool 通过GOPATH指定的工作空间查找 github.com/user/hello 包的源代码

如果已经在包目录里,就可以省略掉包路径

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

这个命令构建 hello 命令,产生一个可执行的binary。然后安装这个binary到工作空间下的 bin 目录,也就是 $HOME/go/bin/hello

go tool 只会在有错误的时候打印输出,所以如果没有内容产生,表示执行成功。

现在可以通过全路径运行程序

$ $GOPATH/bin/hello
Hello, world.

第一个库

现在我们编写一个library并且在 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

如果已经在包源目录下,只需要:

go build

这不会产生输出文件。而是将编译完的包保存到本地构建缓存里。

现在修改 hello.go 来使用它:

package main

import (
      "fmt"
      "github.com/user/stringutil"
)

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

install hello 程序

$ go install github.com/user/hello

这一顿操作后,工作空间应该变成了:

bin/
    hello                 # command executable
src/
    github.com/user/
        hello/
            hello.go      # command source
        stringutil/
            reverse.go    # package source

Package names

Go源文件里的第一行一定是:

package name

其中name是包的默认名称。

(包中的所有文件必须使用相同的名称。)

Go的约定是报名是导入路径最后一个节点: crypto/rot13 的包名是 rot13

可执行命令的包名必须是 package main

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

测试

Go有一个由 go test 命令和测试包组成的轻量级测试框架。

创建一个用 _test.go 结尾的文件,里面的方法命名为 TestXXX 。测试框架会运行每个方法;如果方法调用失败方法比如 t.Error 或者 t.Fail ,测试就被认为失败了。

创建一个 $GOPATH/src/github.com/user/stringutil/reverse_test.go 文件测试 stringutil

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或Mercurial之类的修订控制系统来获取包源代码。go tool使用该属性自动从远程仓库拉去包。比如,本文档里的实例就保存在 github.com/golang/example 。如果你在包的导入路径引入远程URL, go get将会自动获取,构建并且安装它:

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

如果工作空间不存在指定的包, go get 会将它放在GOPATH指定的第一个工作空间内。(如果包存在, go get 会跳过远程获取,就和 go install 的行为一样了)

经过上面的操作后,工作目录结构将会变为:

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

Gihub上托管的 hello 命令依赖同一仓库下的 stringutil 包。 hello.go 文件里的imports使用相同的导入路径规范,所以go get命令可以定位并且安装起来的包:

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

规范是最简单的方式让你的Go包可以对其他的可用


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据之路

大数据之路

阿里巴巴数据技术及产品部 / 电子工业出版社 / 2017-7-1 / CNY 79.00

在阿里巴巴集团内,数据人员面临的现实情况是:集团数据存储已经达到EB级别,部分单张表每天的数据记录数高达几千亿条;在2016年“双11购物狂欢节”的24小时中,支付金额达到了1207亿元人民币,支付峰值高达12万笔/秒,下单峰值达17.5万笔/秒,媒体直播大屏处理的总数据量高达百亿级别且所有数据都需要做到实时、准确地对外披露……巨大的信息量给数据采集、存储和计算都带来了极大的挑战。 《大数据......一起来看看 《大数据之路》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器