Go言語で習作:短いようで長かったGoDocへの道のり

# 前書き
この記事では、[こちらリポジトリ](https://github.com/ak-ymst/go-chatの)のコードをサンプルとして使っています.
また, 動作確認は以下の環境で行いました.

OS: CentOS 7.5
Go言語: version 1.9.4 (yumでインストール)

# GoDoc概要
他の言語にもあるように, Go言語にもソースコードに書かれたコメントをもとに
定義ドキュメントを自動生成する仕組みが用意されています.

例えば, こんな感じにコメントを書いていくと...

```golang

// チャットプログラムパッケージ
package chat

import (
    "net"
    "fmt"
)

// Observer: メッセージオブザーバを意味する構造体。
type Observer struct {
    Senders []Sender // チャット参加メンバ
    Subject <-chan Notification // 通知受信用チャンネル
}

// WaitNotice: 通知受信関数。
//
// 何らかの通知(Notification)を受け取り, 通知種別に合わせて参加メンバ(Senders)へのメッセージ配信
// あるいは参加メンバの追加削除を行う。
func (observer Observer) WaitNotice() {
    // 通知
    notice := <-observer.Subject

    switch notice.Type {
    case Message:
        // メッセージの配信
        for i := range observer.Senders {
            observer.Senders[i].SendMessage(notice.Message);
        }

        break;

    case Join:
        // メンバーを追加
        observer.Senders = appendSender(notice.ClientId, notice.Connection, observer.Senders);

        fmt.Printf("Client %d join, now menber count is %d\n", notice.ClientId, len(observer.Senders));
        break;

    case Defect:
        // メンバーを削除
        observer.Senders = removeSender(notice.ClientId, observer.Senders);

        fmt.Printf("Client %d defect, now menber count is %d\n", notice.ClientId, len(observer.Senders));
        break;

    default:

    }
}

```

こんな感じのドキュメントを生成してくれます

![godoc.png](https://qiita-image-store.s3.amazonaws.com/0/111295/4722d37c-d5a6-d3d8-9c98-c629b17955b7.png)

JavaDoc等のドキュメント生成ツールではアノテーションを使って表示の制御等を
行っていますが, GoDocはMarkdownのように自然に書かれたコメントを一定のルールに従って
HTMLに変換していくようです. 楽でいいですね.

しかし, 実際にコメントを書いて確認するまでになかなかすんなりといかなかったので, 
つまずいた点を備忘録代わりに書いておきたいと思います.

# つまずきポイント
## Docの表示方法がわからない
JavaではSDK付属のJavadocツールを使うことでソースからドキュメントをHTML形式のファイルとして生成することができました.
では, Go言語でもgoコマンドを使ってHTMLファイルを生成するのかと思いきや, さにあらず.
goコマンドのヘルプを見ると__doc__というサブコマンドが用意されているかもしれませんが, これはすでに非推奨であり
現在(特にv1.11以降）では, __godoc__という専用ツールを使って表示を行うようになっています.

表示までの手順は以下の通り.

1-godocを取得する

```
> go get golang.org/x/tools/cmd/godoc
```

2-godocのサーバプログラムを起動する(ポートは空いている任意のポート)

```
> godoc -http=:6060
```

3-ブラウザでgodocサーバの指定したポートにアクセスする

これでドキュメントを確認することができると思われます.


## 自作のパッケージが反映されない
無事ドキュメントを表示できて一安心かと思いきや, ドキュメントに表示されたパッケージ一覧には
自分で作ったパッケージが表示されていないではないですか.
しかしパッケージ一覧をなんとなく眺めていると, Thirdpartyと書かれた次のようなセクションを見つけることができると思います.

![3rdparty.png](https://qiita-image-store.s3.amazonaws.com/0/111295/3edb3480-2984-966e-56ac-5c2dfd45bd1b.png)

このThirdpartyの項目に表示されているパッケージ一覧, どこかで見た構成だと思いませんか？
そう, ここの部分の構成は, `GOPATH`で指定したディレクトリのsrc以下と同じ構成になっているのです.

```
/home/vagrant/go/src
├── github.com
│   ├── golang
│   │   └── lint
│   ├── kisielk
│   │   ├── errcheck
│   │   └── gotool
│   ├── nsf
│   │   └── gocode
│   └── rogpeppe
│       └── godef
└── golang.org
    └── x
        └── tools

```

ということで, そのディレクトリに`my.local`というディレクトリを作成し, 自作ディレクトリを移動すると...

![mypackage.png](https://qiita-image-store.s3.amazonaws.com/0/111295/3c3b1028-15c5-50b1-224f-5add1daaf184.png)


無事ドキュメントに反映されるようになりました.

## プライベートな関数が表示されない
ここまでで, 一通りの問題なくなったとはおもうのですが, もう一点.
GoDocで表示されるのはあくまで公開された関数や構造体のみであり, 非公開な関数や構造体は
表示されません.
どうしても表示したい場合は, ドキュメントのページURLの末尾に`?m=all`というクエリストリングを
付けることで表示することが可能です.

![private.png](https://qiita-image-store.s3.amazonaws.com/0/111295/8e27d689-3bb5-e7bf-8b28-abb1107b37d4.png)


# まとめ
- ドキュメントの作成はGodocツールを使っておこない、表示はブラウザ経由でおこなう
- 自作パッケージはGOPATHディレクトリ以下に配置しないと反映されない
- プライベートな関数もドキュメントに表示したい場合はURLに「?m=all」をつける