初学者がGo言語のImportで上手くいかなくて5時間ぐらい調べた

#### 初めに
未経験の初学者ですが、VScodeでGoを学習中にimportが上手くいかず多分5~7時間調べました。
結果「５時間も調べるとか時間かかり過ぎだろ、30分で十分」と思ったので、
同じような初学者がこんな所で時間を食わぬようまとめてみます。当たり前の事書きます。



`Githubの場合については触れません`
`学習目的のため業務の場合については触れてません`

加筆(2019/10/8)
`Go Modulesについては書いていないのでgo modについても触れていません
src下で行う事を前提としています`


####環境
macOS Mojave: 10.14.5
Go version:  1.12.7
VScode バージョン: 1.37.0

####詰まった時の状況
- File名もPakeage名も間違ってない
- VScodeの設定もおかしいとは思えない
- GOPATHも間違ってない
- File名/Pakege名でimport書いてみるけどエラー

####やった事
- Goの再インストール
- 公式などを読みながらひとつひとつ確認する
- 仮説を思いついたら試す
- 後はひたすら調べる


#結論と解決方法

先に結論だけいうとGoの`import補完機能`を味方につけるのが良いのではないか思います。

それが出来なくって困ってるんだよ　という方は多分私と同じかもしれません。

私も何回試してみてもならなくて調べて全部やり直したら補完してくれて「そういう事かーい」ってなった人間です。
私の場合は__ボケボケの理解しかせずただ調べてそれっぽい形__にしていたのが全ての原因でした。
設定さえおかしくなければimport補完が味方してくれるのではないでしょうか。


######参考記事
[Go公式サイト]:https://golang.org/
[Getting started with Go]:https://medium.com/rungo/working-in-go-workspace-3b0576e0534a
[Everything you need to know about Packages in Go]:https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc
[VScode公式サイト]:https://code.visualstudio.com/docs/setup/setup-overview
[GitHub:GOPATH]:https://github.com/golang/go/wiki/GOPATH
[vscodeの利用に必須な”ワークスペース”の概念]:https://prius.cc/itya/20181218_vscode-workspace


- [Go公式サイト] <==(公式からヒント得て調べました)
- [GitHub:GOPATH]　<==(公式からのリンク)
- [Getting started with Go]　<==(この人の記事で理解度がグッと上がりました)
- [Everything you need to know about Packages in Go]　<==(上と同じ人の記事です)



#Go再インストール　〜再確認〜



そもそもGoをインストールした時点でどうなってたんだ？と思ったので初めからやり直しました。
コマンドを叩いて確認

```:/usr/local/go
/
├ usr/
 ├ local/
  ├ go/
   ├ この先は調べてないのでわからないですがGoがGoであるための場所のようです
```
```:Users/username/go
Users/
┣ username/
  ├ Go/
   ├ bin
   ├ pkg
   ├ src
```
これがインストール済んだ時点で作成されているディレクトリ（`/usr/local/go`,`Users/username/go`)みたいです。

次に`GOPATH`と`GOROOT`を確認します。　コマンド`go env`で一覧を表示してみると
`GOPATH="/Users/username/go"`
`GOROOT="/usr/local/go"` と自動で設定されております。 
どんな意味があるのかと思ったので次に参考記事を見てみます。

##調べてみる

[Go公式サイト]より一部抜粋（google翻訳使いました...）

>__概念__
>> Goプログラマは通常、すべてのGoコードを単一のワークスペースに保持します。

>__ワークスペース__
>ワークスペースは、ルートに2つのディレクトリがあるディレクトリ階層です。
>>- src Goソースファイルが含まれている
>>- bin 実行可能なコマンドが含まれています

>__GOPATH環境変数__
>>GOPATH環境変数は、ワークスペースの場所を指定します
>>別の場所で作業する場合は 、そのディレクトリへのパスをGOPATH設定する必要があります 

公式のリンクにある[GitHub][GitHub:GOPATH]より一部抜粋（google翻訳使いました...）
>__GOPATH__

>Introduction
>>GOPATH環境変数は、Goプロジェクトとそのバイナリのソースを含む$ GOROOT以外のディレクトリを指定するために使用されます。

>Tips and tricks
>>単一のGOPATHを使用する
>>GOPATHがディレクトリのリストである場合でも、一般に、マシン上のすべてのGoコードに単一のGOPATHを使用すれば十分です。>>「go get」で取得したすべてのパッケージには一意のURL（したがってディスク上の一意のパス）があるため、Goツールでビルド>>する場合、複数のGOPATHを持つ必要はほとんどありません。

[Everything you need to know about Packages in Go]　より

> Goは最初にディレクトリ内のパッケージディレクトリを検索し、GOROOT/srcが見つからない場合はGOPATH/srcを探します

また、[Getting started with Go]　を読んでみると
ワークスペースという考え方、仕組みがGoの管理を助けているようです。



という事で

- Goの作業はワークスペース内で行うのが基本とされている
- ワークスペース内のどこで行えばいいいかといえば最初に作られた`bin`,`pkg`,`src`の中の`src`
- `GOPATH`, `GOROOT`は基本いじらないで大丈夫
- `GOPATH`は`Goのワークスペース`の場所を指定している
- 基本上記で十分みたいですが、状況に応じてPATH設定を追加する　という流れになるのではないかと考えます


ずれた考えかも知れませんが、importの自動補完を味方につけるには、このワークスペースとGOPATHの関係をさらっとでも理解しないとimportが敵になりそうですね。

```
Users/
┣ username/
  ├ Go/  
   ├ bin
   ├ pkg
   ├ src <- ここでコード作成などを行う
```

#という事で試す
そんな事も知らずに雰囲気でやってた私のGoの学習用フォルダーは

```
Users/
┣ username/
  ├ Go/  <-ワークスペース
   ├ bin
   ├ pkg
   ├ src
   ├ qita <- やっちまってる
      ├ main.go
      ├ jojo
        ├ jojo.go 
      ├ dio
        ├ dio.go

```

これだと

```go:main.go

import (
	"fmt"
	
  
	// GOPATHは（Users/username/go）

	// エラー(これでいいハズなのに） 
	"qita/jojo"
	// cannot import absolute path　とエラー（GOPATH/qita/jojoのつもり)
	"/qita/jojo"
	// 相対パスだと認識される。けど自動補完はされません。相対パスは推奨されてないようです。
	"./jojo"
)
func main() {
	fmt.Println("Jojo:" + jojo.Voice)
}
```
なので

```
Users/
┣ username/
  ├ Go/  <-ワークスペース
   ├ bin
   ├ pkg
   ├ src
      ├ qita <- src下に移動(GoはGOPTAH/srcを探すため）
        ├ main.go
        ├ jojo
          ├ jojo.go 
          ├jojo2    <-試しに追加 
          ├jojo2.go <-試しに追加
        ├ dio
          ├ dio.go

```
これで試す

```go:main.go
package main

import (
	"fmt"
	
	// GOPATHは（Users/username/go）

	// 自動で補完されました　成功
	"qita/jojo"

	// cannot import absolute path　とエラー （前回と変わらず）
	"/qita/jojo"

	// 試しに qita/jojo/jojo2 というのも作りましたが自動補完してくれました　成功
	"qita/jojo/jojo2"

	// 今度は相対パスだとエラー（今度はエラー）(GOPATHかGOROOTの中じゃないと探せないよとエラー）
	"./jojo"
)

func main() {
	fmt.Println("Jojo:" + jojo.Voice) //出力 Jojo: Oraa!

	fmt.Println("Jojo2:" + jojo2.Voice) //出力 Jojo2: Mudaa!
}
```
とりあえずはimport補完が効くようようになりました

## 結局importは...
相対パスの件など調べてみましたがちゃんとはわからなかったです。推奨はされてないようです。
GitHubの場合もありますし、設定できても自動補完出来たりできなかったりする時もあるようです。

ただ`ワークスペース`と`GOPATH`に気をつけて、`src`下でコードを作成しているぶんには、
通常のimportの書き方で済むハズなのでこれでエラーが起こる可能性は減ったと思います。

__結局importはちょっとややこしい__

後は都度調べて行きましょう！


##参考になれば幸いです
至らない所もあるかと思いますが、間違っているぞ！などあればご指摘のほどよろしくお願いします。
またガイドラインに反してる、反してはないけどよろしくない部分がありましたらお手数ですがご指摘のほどお願いいたします。


---
---
###蛇足
初めての投稿でしたがこの記事書くのに多分１０時間くらいかかったと思います。（白目
私と同じような人にとってわかりやすければ何よりです。

なんで書こうと思ったかというと
高校時代に自作PCの本きっかけでコンピューターに触れましたが（金なくて作れませんでした）

その時にlinuxを知り、オープンソースであると、有志が作ってんだぞと、無料だぞと、オープンソース文化を知った瞬間でした。
PC自作の時も今プログラミングを勉強してる時もオープンソース文化に助けてもらってるなぁと感じたんですよね
この先続くのか知らないですけど、ましてや未経験ですけど、
でも書いておこうと。名無しの有象無象になって貢献しよう思いました。

書くのも、伝えるのも違った面白さがありますが、少なくとも楽では無いですね（汗
`改めてオープンソース文化に寄与されてる方々にこの場を借りて感謝申し上げます`

もっと質の良いものが書けるよう精進致します。