ローカル環境のみでの Go Modules と自作パッケージ

# 概要
自作 package インポートできねーじゃんっていろいろやった結果。
GOPATH 配下にディレクトリがないときの話。

# 環境
[windows への go インストール](https://qiita.com/tkj06/items/b174f48358f0cfe7cc31)

go のバージョン、GOPATH、GOROOT、GO111MODULE の値は以下の通り。

```
C:\goworkspace\gomodulesample>go version
go version go1.13.1 windows/amd64

C:\goworkspace\gomodulesample>go env GOPATH
C:\Users\sampleuser\go

C:\goworkspace\gomodulesample>go env GOROOT
c:\go

C:\goworkspace\gomodulesample>go env GO111MODULE
on
```

# ファイル1つだけ
至極単純なやつです。

C
└goworkspace
　　└gomodulesample
　　　　└ sample.go

```go:C/goworkspace/gomodulesample/sample.go
package main

import "fmt"

func main() {
	fmt.Print("testdesu")
}
```

## ビルド
実行可能な形式のファイル (windows なので .exe 形式)が出力されているのがわかります。

```
C:\goworkspace\gomodulesample>go build sample.go

C:\goworkspace\gomodulesample>dir
2019/12/13  15:21    <DIR>          .
2019/12/13  15:21    <DIR>          ..
2019/12/13  15:21         2,074,112 sample.exe
2019/12/13  15:15                67 sample.go
```

## 実行
go run でもできます。

```
C:\goworkspace\gomodulesample>sample.exe
testdesu

C:\goworkspace\gomodulesample>go run sample.go
testdesu
```

# 自作の別ディレクトリの 別 package をインポート
C
└goworkspace
　　└gomodulesample
　　　　├ sample.go
　　　　└ exampledir
　　　　　　└example.go

```go:C/goworkspace/gomodulesample/exampledir/example.go
package exampledir

func Example() string {
	return "This is example."
}
```

相対パスで行けるかと思ってました。

```go:C/goworkspace/gomodulesample/sample.go
package main

// 相対パスで行ける。。。？
import (
	"fmt"
	"./exampledir"
)

func main() {
	fmt.Print(exampledir.Example())
}
```

## ビルド
`cannot find module for path` 、モジュールがありませんよとのエラー。

```
C:\goworkspace\gomodulesample>go build sample.go
build _/C_/goworkspace/gomodulesample/exampledir: cannot find module for path _/C_/goworkspace/gomodulesample/exampledir
```

## モジュール化とやらをやってみる
失敗。
自動的に名前を推測できない場合(git などのバージョン管理システムの管理下にない場合など)は、モジュール名を明示的にしなければならないらしい。

```
C:\goworkspace\gomodulesample>go mod init
go: cannot determine module path for source directory C:\goworkspace\gomodulesample (outside GOPATH, module path must be specified)

Example usage:
        'go mod init example.com/m' to initialize a v0 or v1 module
        'go mod init example.com/m/v2' to initialize a v2 module

Run 'go help mod init' for more information.
```

参考
https://github.com/golang/go/wiki/Modules#why-does-go-mod-init-give-the-error-cannot-determine-module-path-for-source-directory

## モジュール化(モジュール名を明示的に)
なんとなくディレクトリ名とちょっと違った名前でやってみる。

```
C:\goworkspace\gomodulesample>go mod init modulesample
go: creating new go.mod: module modulesample
```

go.mod ファイルが作成される。依存パッケージ管理とかでありそうなやつである。

```:C/goworkspace/gomodulesample/go.mod
module modulesample

go 1.13
```

こんな感じのディレクトリ構成になる。

C
└goworkspace
　　└gomodulesample
　　　　├ sample.go
　　　　├ `go.mod`
　　　　└ exampledir
　　　　　　└example.go


## import を go mod init で指定したモジュール名を使ったものに変更

```go:C/goworkspace/gomodulesample/sample.go
package main

import (
	"fmt"
	"modulesample/exampledir"
)

func main() {
	fmt.Print(exampledir.Example())
}
```

### 再びビルド
実行可能形式ファイルの名前が指定したモジュール名(`modulesample`)になっていることがわかります。

```
C:\goworkspace\gomodulesample>go build

C:\goworkspace\gomodulesample>dir
2019/12/13  15:27    <DIR>          exampledir
2019/12/13  15:45                29 go.mod
2019/12/13  16:03         2,074,112 modulesample.exe
2019/12/13  15:59               120 sample.go
```

### 実行
無事自作 package の関数が呼ばれています。

```
C:\goworkspace\gomodulesample>modulesample.exe
This is example.

C:\goworkspace\gomodulesample>go run sample.go
This is example.
```