LoginSignup
3
3

More than 1 year has passed since last update.

Pythonしか知らない人がGoに入門した時モジュール管理がわからんかった

Last updated at Posted at 2021-07-15

注意

この記事は 2021/03/16 にGoを始めたときに書いた記事です。
あとからもうちょい修正しようと思って寝かしてたんですが、結局直さなかったので
途中までになりますが、載せておきます。

Goはじめたい理由

噂によるとGoは動作が速いらしいので、PythonのFlaskで書いてたAPIをGoのEchoで置き換えたい。
大体それだけが理由です。()

用意したもの

Windows 10
- Macは持っていないのでとりあえず

Python 3.8.6 windows/amd64
- いつもよく使っているPythonくん
 - 公式サイトからインストーラをダウンロードして実行しただけ

Go 1.15.6 windows/amd64
 - 割と最近入れたGoくん
 - 公式サイトからインストーラをダウンロードして実行しただけ

VSCode
- メインで使っているエディタ

まずはじめにしたこと

Go 入門 でググってみる。
すると Go言語の初心者が見ると幸せになれる場所 が出てきたので
各ページを若干読んでみることとした。

この中だと、友人いわく A Tour of Goがおすすめとのことらしいが、とりあえず何かしら作ってみないと構文を覚えられる気がしないので、ハローワールド、BMI、ガチャを作ってみることにした。

VSCodeを設定しよう

VSCode → 拡張機能タブ → Goと検索 → 一番上に出てくる拡張機能をインストールする。
その時点で Goが綺麗に表示されるようになるはず。

よくわからないがおすすめっぽいので、Go言語をVSCodeで開発する環境をインストールするを読んで、拡張機能の依存関係もインストールした。

Helloworldをしよう

まぁこれは一瞬でできる。見た通りだよなって感じだったので特に苦労していない。

main.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello world!")
}

このファイルをVSCodeで作って保存する。
そして、F5キーを押すと実行されて Hello world! と出るはず。

Hello world! という文字を 別モジュールから読み出したい

ハローワールドはわかったが、よくあるやつすぎて面白くないので、 Hello world! って文字列を 別ファイルから読み出したくなった。

Pythonではpip Goでは Go modules が定番?

チュートリアルの一部では GOPATH がどうこうという話が出てきていたが、 最近(Go 1.11以降)では Go modules という依存関係管理ツールが使われることが多いらしい。Go言語の依存モジュール管理ツール Modules の使い方を読んで、やってみようとした。

とりあえずまず、コマンドプロンプトで go env -w GO111MODULE=onする。
次に main.goと同じフォルダ内で、 fixed_valueというフォルダを作り、 go mod init fixed_value してみた。
すると、go.mod というファイルができて、モジュールとして扱ってくれるようになる。
最後にパッケージとして

fixed_value/fixed_value.go
package fixed_value

var Message string = "Hello world"

っていうのを作ってみた。

これをmain.goで読み出したいので

main.go
package main

import (
    "fmt"

    "./fixed_value"
)

func main() {
    fmt.Println(fixed_value.Message)
}

Pythonの__init__.pyみたいには動かない

で、実行してみると build command-line-arguments: cannot find module for path _/D_/Documents/Gits/go-practice/helloworld/fixed_value と怒られてしまった。 どうやら Pythonの __init__.py のつもりで パッケージフォルダ内に置いても動かないようだった。 (VSCodeのlintが起きてる場合はそもそも保存させてくれなくて実行できない)

じゃあどうするの?

相対インポートというものは、許されざる悪みたいな立ち位置にいるらしく、絶対インポートしないとダメらしい。
絶対インポートと言っても、フォルダのパスではなく、リポジトリのパスを入れるってことらしい。

リポジトリを使う絶対インポート??

まずさっき 作った fixed_value/go.mod は削除する。その上で 直下に改めて go.modを作成する。 その際には、 go mod init github.com/Dosugamea/go-practice/helloworld というようにリポジトリ名(+必要ならフォルダパス) を付ける。 これで go.modを作った。じゃあどうやって main.goからfixed_valueをインポートをするのかというと以下のようにする。

main.go
package main

import (
    "fmt"

    "github.com/Dosugamea/go-practice/helloworld/fixed_value"
)

func main() {
    fmt.Println(fixed_value.Message)
}

これでいざできたと思って実行しようとすると、実は実行できない。先に go.mod と fixed_value を コミットして リポジトリにプッシュした後で初めて main.goが実行できるようになるようだ。 go.modの中で Replaceという細工をして、相対インポートをさせる方法もあるが、リポジトリにプッシュしてしまうのが一番丸いらしい。

これでなんとなく Goでのモジュールの扱い方がわかった。gg。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3