如何写高大上的 godoc(Go 文档)

做 Go 开发时,我们在开源项目的主页上我们经常可以看到这样的一个徽章:


点击徽章,就可以打开 godoc.org
的网页,网页中给出了这个开源项目所对应的 Go 文档。作为 Go 语言的新手,我一度以为, godoc.org
上面的文档是需要开发者上传并审核的——要不然那些文档咋都显得那么专业呢。

然而当我写自己的轮子时,慢慢的我就发现并非如此。 划重点
:在 godoc.org
上的文档,都是 Go 自动从开源项目的工程代码中搜集、格式化后展现出来的。换句话说,每个人都可以写自己的 godoc
并且展示在 godoc.org
上,只需要遵从 godoc 的格式标准即可,也不需要任何审核动作。

本文章的目的是通过例子,简要说明 godoc 的格式,让读者也可以自己写一段高大上的 godoc
。以下内容以我自己的 jsonvalue
仓库为例子。其对应的 godoc 在 这里
。读者可以点开,并与代码中的内容做参考对比。

本文地址: https://segmentfault.com/a/1190000020944376
,首发于 云+社区

什么是 godoc

顾名思义,godoc 就是 Go 语言的文档。在实际应用中, godoc
可能可以指以下含义:

https://godoc.org
godoc

我们从 Go 自带的 godoc
工具讲起吧。前面我们说到的 godoc.org
,是 Go 最为官方的文档网站。其中我们可以查阅 Go 原生 package 的文档说明。而 godoc
命令的作用,则是可以让我们在本地建立一个属于自己的 godoc
网站服务(官方的 godoc
其实也基本上是用同一个工具建立起来的)。

自建的 godoc
有两个作用,一是解决某局域网内无法访问 godoc.org
的尴尬,另一个则是可以本地调试自己的文档。

我们可以用下面的命令在本地启动自己的 godoc
服务:

godoc -http=127.0.0.1:6060 -play

或者简写为:

godoc -http=:6060 -play

在浏览器输入 http://127.0.0.1:6060
之后,就可以看到熟悉的 Go 文档页面了:


原理上, godoc
读取的包路径来自于 $GOROOT
。因此,如果你要让本地的 godoc
认识并解析你自己的开发包,就应该在 $GOROOT
目录下按照路径结构放好自己的工程代码——软链接也是支持的。比如笔者的 jsonvalue
包,我放在了这个路径下: ~/project/github.com/Andrew-M-C/go.jsonvalue
,于是我就在 $GOROOT
下建了软链接:

$ go env | grep GOROOT | sed 's/GOROOT=//g' | xargs cd
$ ln -s ~/project/github.com ./

然后在浏览器中输入 http://127.0.0.1:6060/pkg/github.com/Andrew-M-C/go.jsonvalue/
,就可以看到和 godoc.org
一样的页面了。

godoc 一览

Go 秉承 “注释即文档” 的理念,符合 godoc
的文档均从 Go 代码中提取并生成。我们还是从 jsonvalue
的 godoc 来看,一个一个说明。在 godoc 中,文档包含三大部分:

组成 作用
Overview 总览 包含包的 import 语句和概要说明
Index 目录 包含包中可见性为 public 的常量、类型、方法、函数的总目录及说明
Examples 示例 包含文档中所有示例的快速跳转
Files 文件 列出了包中所有代码文件的超链接

其中第四部分无关紧要。下面我们按顺序说明前三部分

godoc 的 Overview

Package jsonvalue 的 Overview 部分包含了三部分内容:

  • import 语句
  • 文字说明
  • 代码部分

其中 import 部分是 godoc 自动按照 URL 生成的,这个不用管。至于文字部分和代码部分,godoc 都是从源码中提取出来的。提取的原则是:

  • 在代码中所有 package jsonvalue
    语句中,找到其上方紧跟着的 // jsonvalue XXX
    或者是 /* jsonvalue XXX */
    注释块
  • 注释块可以有多行,但必须是连续的 //
    或者 /* XXX */
    开头。如果需要换行,则留一行空注释
  • 如果找到多个符合条件的注释,则按照文件字母序显示——建议把 Overview 放在一个注释块中,而不要分散撰写。

比如 jsonvalue 的 Overview 说明,统一放在 doc.go
中,这个文件中只有 package jsonvalue
语句以及包说明——这也是不少文章中推荐的做法。

Overview 的文字部分

请读者打开 doc.go
,然后对比 godoc
,就可以对照着看到文字部分是怎么被 godoc 呈现出来的。

Overview 的代码部分

在注释中,如果在 //
后面的注释文本中,如果以 tab
进行了锁进,那么 godoc
会将这一行视为代码块。比如下面这一段:


其中 ” As a quick start:
” 行的左边分别为:两个斜杠 + 一个空格。这一行, godoc
视为普通文字;而其余部分的左边为:两个斜杠 + 一个空格 + 一个tab,被 godoc
视为代码部分。于是我们在 godoc
网页上,就可以看到这样的显示结果了:


godoc 的代码文档

godoc
工具会搜寻代码中所有源码文件(自测文件除外),然后展示到页面上。搜索的依据如下:

godoc

不过在源码说明中,更多的采用代码示例来说明逻辑,因此在这一环节中,代码块比较少用。

这里我用 jsonvalue

At()

函数为例。在 代码
中,对于 Set()
函数我是这么写的(请无视我蹩脚的英文):

// At completes the following operation of Set(). It defines posttion of value in Set() and return the new value set.
//
// The usage of At() is perhaps the most important. This function will recursivly search for child value, and set the new value specified by Set() or SetXxx() series functions. Please unfold and read the following examples, they are important.
func (s *Set) At(firstParam interface{}, otherParams ...interface{}) (*V, error) {
    ......
}

godoc 解析并格式化效果如下:


godoc 的代码示例

读者可以注意到,在我的 At()
函数下,除了上文提到的文档正文之外,还有五个代码示例。那么,文档中的代码示例又应该如何写呢?

首先,我们应该新建至少一个文件,专门用来存放示例代码。比如我就把示例代码写在了
example_jsonvalue_test.go

文件中。这个文件的 package
名也不得与当前包名相同,而应该命名为 包名_test
的格式。

示例代码的声明

如何声明一个示例代码,这里我举两个例子。首先是在 At()
函数下名为 “Example (1)” 的示例。在 代码
中,我把这个函数命名为:

func ExampleSet_At_1() {
    ......
}

这个函数命名有几个部分:

函数名组成部分 说明
Example 这是示例代码的固有开头
Set 表示这是类型 Set
的示例
第一个下划线 _ 分隔符,在这个分隔符后面的,是 Set
类型的成员函数名
At 表示这是函数 At()
的示例,搭配前面的内容,则表示这是类型 Set
的成员函数 At()
的示例
第二个下划线 _ 分隔符,在这个分隔符后面的内容,是示例代码的额外说明
1 这是示例代码的额外说明,也就是前面 “Example (1)” 括号里的部分

另外,示例代码中应该包含标准输出内容,这样便于读者了解执行情况。标准输出内容在函数内的最后,采用 // Output:
单独起一行开头,剩下的每一行标准输出写一行注释。

相对应地,如果你想要给(不属于任何一个类型的)函数写示例的话,则去掉上文中关于 “类型” 的字段;如果你不需要示例的额外说明符,则去掉 “额外说明” 字段。比如说,我给类型 Opt
写的 示例
就只有一个,在 代码
中,只有一行:

func ExampleOpt() {
    ........
}

甚至连示例说明都没有。

如果一个元素包含多个例子,那么 godoc
会按照字母序对示例及其相应的说明排序。这也就是为什么我干脆在 At()
函数中,示例标为一二三四五的原因,因为这是我希望读者阅读示例的顺序。

在官网上发布 godoc

好了,当你写好了自己的 godoc
之后,总不是自己看自己自娱自乐吧,总归是要发布出来给大家看的。

其实发布也很简单:当你将包含了 godox 的代码 push 之后(比如发布到 github 上),就可以在浏览器中输入 https://godoc/org/${package路径名}
。比如 jsonvalue
的 Github 路径(也等同于 import 路径)为 github.com/Andrew-M-C/go.jsonvalue
,因此输入 godoc.org/github.com/Andrew-M-C/go.jsonvalue

如果这是该页面第一次进入,那么 godoc.org
会首先获取、解析和更新代码仓库中的文档内容,并且格式化之后展示。在页面的底部,会列出该 godoc 的更新时间。


如果你发现官网上的 godoc
内容已经落后了,那么可以点 “ Refresh now
” 链接刷新它。

接下来更重要的是,把这份官网 godoc
的链接,附到你自己的 README 中。还是点上图的 “ Tools
” 链接,就可以在新页面中,看到相应的 godoc
徽标的链接了。有 html
markdown
格式任君选择。


本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
进行许可。

原作者: amc
,欢迎转载,但请注明出处。

原文标题: 如何写高大上的 godoc(Go 文档)

发布日期:2019/10/24

原文链接: https://cloud.tencent.com/developer/article/1526609