如何写 Go 代码?

On 2023/06/29, in Go, by admin

原文:http://golang.org/doc/code.html

简述

这篇文档描述了如何去写一个新的 package 和怎么去测试。本文假设你已经按照安装文档装好Go。

在修改一个存在的 package 或者新建立一个package,确保先发一封邮件到 mailing list,告诉大家你想做什么。这样有助于不要重复造轮子,在写代码之前最好讨论下。

社区资源

如果想获取实时帮助,可以加入 Freenode 上 IRC 频道 #go-nuts。

Go 语言官方邮件列表是 Go nuts.

Bugs 可以参考 Go issue.

对于那些想尝试开发代码的用户,这里有另外一个邮件列表 golang-checkins,邮件里包含了那些刚提交到 Go 代码库的消息。

建立Go包

下面的源码假设 package 的导入路径是 x/y,约定下保存的路径是:$GOROOT/src/pkg/x/y

Makefile

这将是很好的利用 Go-specific 工具里安排源码结构,如何按照顺序和构建代码。Go 使用 GUN make。所以首先在一个新的package 文件夹里建立一个 Makefile。最简单的做法就是从 src/pkg/container/vector/Makefile 源码包里拷贝一份。

include ../../../Make.$(GOARCH)

TARG=container/vector
GOFILES=\
        intvector.go\
        stringvector.go\
        vector.go\

include ../../../Make.pkg

当然在上面的源码包之外写一个新的 package ,通常的 Makefile 如下:

include $(GOROOT)/src/Make.$(GOARCH)

TARG=mypackage
GOFILES=\
        my1.go\
        my2.go\

include $(GOROOT)/src/Make.pkg

第一行 include 标准的定义和规则,package 的路径一般相对路径来代替 $(GOROOT)/src ,这样做到目的就是防止 make 时候 $(GOROOT) 含有空格,这样做很方便开发中使用Go。

TRAG 是包安装路径,这行就是其他程序导入到名字。在 Go 源码中,这个名字必须和文件夹中的 Makefile 中的一致,不需要 $GOROOT/src/pkg/ 前缀。在源码之外,你可以任意起名而不要和标准 package 的重名即可。常见的做法是独立一个 package 名:myname/tree, myname/filter,确保你的代码在 myname 里,运行 make install,将会编译后把二进制文件放入 $GOROOT/pkg,可以很方便的找到。

GOFILES 放入文件内需要编译的源码列表。多行用 \ 字符隔开。

如果想在 Go 源码树中新建包,需要添加列表到 $GOROOT/src/pkg/Makefile 中作为标准库编译,编译运行:

cd $GOROOT/src/pkg
./deps.b

更新依赖文件 Make.deps (这是每次 make all 或者 make build 都需要)

Go 源文件

在每个源码里第一行的名字应该是 Makefile 里面定义的 package 名,这里的 name 是作为默认的名字导入。(包里的每个 package 名都应该是同样的名字)Go的惯例是用路径的最后一个元素作为名字,比如 “crypto/rot13″ 应该是 rot13。到目前为止,Go 是依靠 package 名字来确定一个二进制的文件,当然可能会很快的取消。

Go 是在一个包内编译源码文件,在一个文件定义常量,变量,类型或者函数,在其他文件内适用不需要再定义和声明。

想写一个干净而优美的 Go 代码不在本文范围。请参考深入 Go 文档吧。

测试

Go 有一个轻量级的测试代码框架:gotest。编写一个测试代码,只需要新建一个跟你源码名字一样,加上:_test.go 即可,测试函数一般是 func TestXXX (t *testing.T)。每次运行测试其中的函数。如果想返回错误的话一般是返回: t.Error 或 t.Fail,测试时候就会抛错。详细 gotest 测试方法请参考:http://golang.org/pkg/testing/

*_test.go 不需要在 Makefile 中声明。

运行测试,编译时候 make test 即可,和 gotest 效果一样。如果想单独测试某一个源码,比如:one_test.go,则运行:gotest one_test.go。

如果你的修改影响性能,可以添加一个性能测试函数(参考:http://golang.org/pkg/testing/),然后运行:gotest -benchmarks=.

当你新的代码已经通过测试,也能运行,你就可以 review 和 commit.  http://golang.org/doc/contribute.html

一个测试的例子

这是一个名字叫 numbers 测试 package ,定义了一个叫 Double 的函数,返回一个整型,结果是输入的参数乘以2。一共有三个文件。

第一个是 numbers.go

package numbers

func Double(i int) int {
        return i * 2
}

第二个是测试文件 numbers_test.go

package numbers

import (
        "testing"
)

type doubleTest struct {
        in, out int
}

var doubleTests = []doubleTest{
        doubleTest{1, 2},
        doubleTest{2, 4},
        doubleTest{-5, -10},
}

func TestDouble(t *testing.T) {
        for _, dt := range doubleTests {
                v := Double(dt.in)
                if v != dt.out {
                        t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out)
                }
        }
}

最后是 Makefile 文件

include $(GOROOT)/src/Make.$(GOARCH)

TARG=numbers
GOFILES=\
        numbers.go\

include $(GOROOT)/src/Make.

运行 make install 将会构建和安装包到 GOROOT/pkg/ 文件夹内(他在系统的任何地方导入调用)。

运行 make test (或者 gotest)将会重新构建包,并会运行 numbers_test.go 中的 TestDouble 函数。如果输出 “PASS” 则表示测试成功通过。如果不是2到3的倍数,将会看到错误报告。

更详细的请查看 gotest 文档测试package文档。

Tagged with:  

7 Responses to 如何写 Go 代码?

  1. [...] This post was mentioned on Twitter by Tux Yeates and Henry Huang, smallfish. smallfish said: 《如何写 Go 代码?》 https://chenxiaoyu.org/blog/archives/297 [...]

  2. MadGo 说:

    很好,Go现在的中文文档确实太匮乏了

  3. Chingli 说:

    你好,刚弄了一个Go语言社区:gocoding.org,你能不能把这篇文章发到社区Wiki上?

  4. Chingli 说:

    因为是wiki,将来会有改动的,没有授权是不能原封不动地放上去的。

  5. hoorace 说:

    鱼哥不是葱白go么?继续多谢几篇。

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

iBlog by PageLines

WP SlimStat