48
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2023で記事投稿!

ちゃんと理解するGo言語開発環境構築:go mod initとその必要性

Last updated at Posted at 2023-06-30

はじめに

Go言語(通称Golang)は、高速で堅牢なプログラムを書くためにGoogleによって開発された静的型付けされた言語です。しかし、初めてGo言語に触れるとき、go mod init というコマンドに遭遇し、何をしているのか混乱するかもしれません。この記事では、そのコマンドが何であるか、またそれがなぜ必要なのかを詳しく説明します。

Goモジュールとは何か?

Go言語では、コードのパッケージを整理し、バージョン管理するためにモジュールという概念が導入されています。モジュールはGoのコードの集合で、特定のディレクトリ内に配置されます。各モジュールは一意の名前を持ち、それを通じて他のモジュールから参照されます。

go mod initとは何か?

go mod init は、新しいGoモジュールを初期化するためのコマンドです。このコマンドを実行すると、モジュール名をパラメータとして受け取り、その名前で新しいモジュールを作成します。さらに、このコマンドはgo.modという特別なファイルを生成します。このファイルには、モジュール名とモジュールが依存する他のモジュールの情報が含まれます。

たとえば、次のコマンドを実行すると、github.com/ユーザー名/GoProjectという名前の新しいモジュールが作成されます:

go mod init github.com/ユーザー名/GoProject

なぜgo mod initが必要なのか?

なぜgo mod initが必要なのか?

Go言語とPythonを比較すると、パッケージ管理の手法に大きな違いがあります。Pythonではスクリプトを書いて直接実行できる一方、Goではコードが属するパッケージを明示的に示す必要があります。この違いは、両言語の本質的な特性に起因します。

Goはコンパイル言語であり、実行可能なバイナリを生成する前にすべての依存関係を解決しなければなりません。これに対し、Pythonはインタープリタ言語で、実行時に依存関係を動的に解決できます(例えばimportlib.import_module()を使って)。Goの各ファイルはpackage宣言でパッケージを明示しますが、Pythonではディレクトリ構造によって暗黙的にパッケージが定義されます。

Go 1.11以降で導入されたモジュールシステムは、依存関係の管理とバージョニングを言語コア機能として統合しています。これは、Pythonの複数の依存関係管理ツール(pip、virtualenv、poetryなど)とは対照的です。Goは静的リンクを使用して単一の実行可能ファイルを生成するため、すべての依存関係情報が必要になります。

go.modファイルはプロジェクトの依存関係とそのバージョンを明確に定義し、異なる環境での再現性を向上させます。また、Goのモジュールシステムは、同一プロジェクト内で異なるバージョンの同じパッケージを使用することを可能にし、名前空間の衝突を防ぎます。

このコンテキストにおいて、go mod initコマンドは単なる初期化ステップではなく、Goプロジェクトの基盤を形成する重要な役割を果たします。このコマンドは新しいGoモジュールを初期化し、go.modファイルを作成してプロジェクトのルートディレクトリとモジュール名を定義します。これにより、後続のgo getgo buildコマンドがこの情報を使用して依存関係を適切に管理できるようになります。

したがって、go mod initはGoプロジェクトにおいて、依存関係の管理、バージョニング、そしてプロジェクトの構造化を確立する重要なステップとなっています。これにより、大規模なプロジェクトでもコードの管理が容易になり、開発の効率性と信頼性が向上します。

Go言語でのモジュール管理: ハンズオン

まず最初にgo mod initを実行し、新しいGoモジュールを初期化します。ここでは先ほどと同様にgithub.com/ユーザー名/GoProjectという名前のモジュールを作成しましょう。

go mod init github.com/ユーザー名/GoProject

これにより、現在のディレクトリにgo.modというファイルが作成されます。このgo.modファイルは以下のような内容となっています:

module github.com/ユーザー名/GoProject

go 1.15

このgo.modファイルは、あなたのプロジェクトがどのパッケージに依存しているのかをGoツールチェーンに伝えます。例えば、あなたのプロジェクトがgithub.com/gin-gonic/ginという外部パッケージに依存しているとしましょう。その場合、そのパッケージをインストールするためには以下のコマンドを実行します:

go get github.com/gin-gonic/gin

このコマンドを実行すると、Goはこのパッケージをダウンロードし、あなたのプロジェクトで使用できるようにします。さらに、go.modファイルも自動的に更新され、以下のようになります:

module github.com/ユーザー名/GoProject

go 1.15

require github.com/gin-gonic/gin v1.7.0 

このrequire行が、あなたのプロジェクトがgithub.com/gin-gonic/ginパッケージに依存していることを示しています。このようにGoのモジュールシステムは、プロジェクトの依存関係を明確に管理するのに役立ちます。

ツールチェーンとは?

ツールチェーンとは、一連のプログラミングツールのことを指します。これらのツールは一緒に動作して、コードの編集からテスト、ビルド、デプロイまでの一連の開発プロセスを支援します。Go言語のツールチェーンには、コードのフォーマットを整えるgofmt、パッケージのドキュメントを生成するgodoc、コードをビルドするgo build、テストを実行するgo test、依存パッケージをダウンロードするgo getなどが含まれています。これらのツールは一緒に動作して、Goのコードの開発、テスト、デプロイを円滑に行うことを支援します。

外部パッケージgithub.com/gin-gonic/ginについて

Go言語では、コードの再利用性を向上させるために、パッケージという単位でコードを分割します。これにより、一度書いたコードを他のプログラムでも利用できるようになります。

github.com/gin-gonic/ginは、Goで高性能なHTTP Webフレームワークを提供する外部パッケージの一つです。ginはルーティング、ミドルウェア、JSONバリデーション、テストコード生成など、Webアプリケーション開発に必要な多くの機能を提供しています。

Go言語の強力な点の一つは、これらの外部パッケージを簡単にプロジェクトに取り込むことができる点です。例えば、上記のginパッケージをプロジェクトに取り込むには、単にgo get github.com/gin-gonic/ginというコマンドを実行するだけです。これにより、Goは必要なコードを自動的にダウンロードし、あなたのプロジェクトで使用できるようにします。

では、なぜこのようなモジュール管理が必要なのでしょうか。その答えは、「依存性地獄」を避けるためです。

'依存性地獄'は、一つのアプリケーションが多数のライブラリに依存し、それぞれのライブラリがまた他のライブラリに依存している場合に起こります。これらの依存関係が複雑に絡み合ってしまい、バージョン管理が難しくなります。

しかしGoのモジュール管理では、各モジュールがどのバージョンのパッケージに依存しているかがgo.modファイルに明示的に記録されています。これにより、プロジェクト全体で一貫した依存関係を保つことが可能となります。

また、go.modファイルが存在するディレクトリをベースに、Goのツールはそのディレクトリをモジュールのルートとみなし、依存関係の解決を行います。これにより、モジュール内のすべてのGoファイルが一貫したビルド結果を持つことが保証されます。

以下でpythonとJavaでの比較をしていきます。

Pythonの依存関係管理とモジュール管理

Pythonでは、パッケージの管理は基本的にpipというツールで行います。pipはPythonのパッケージ管理システムで、Pythonのライブラリをインストール、アップグレード、削除するためのコマンドラインツールです。

また、Pythonの依存関係の管理は通常、requirements.txtPipfileといったファイルに依存パッケージのリストを記述することで行います。例えば、requirements.txtファイルに以下のような内容を記述すると、

numpy==1.18.1
scipy==1.4.1

これらのパッケージはpip install -r requirements.txtコマンドで一括でインストールすることができます。

さらに、Pythonではプロジェクトごとに独立した環境を作成するためのツール(venvpipenvなど)が提供されており、これらを用いることでプロジェクトごとに異なるパッケージのバージョンを管理することが可能です。

Javaの依存関係管理とモジュール管理

Javaでは、依存関係の管理は主にMavenGradleといったビルドツールで行います。これらのツールはpom.xmlbuild.gradleといった設定ファイルに依存ライブラリのリストを記述することで、必要なライブラリを自動でダウンロードしてプロジェクトに組み込む機能を提供しています。

Java 9以降では、モジュールシステムが導入され、大規模なプロジェクトのコードをより効率的に管理する機能が提供されています。モジュールは関連するパッケージとリソースの集合で、モジュール間の依存関係を明示的に指定することができます。

このように、PythonもJavaも独自の方法でパッケージや依存関係の管理を行っています。Go言語もこれらの概念を持っており、それぞれが独自の方法で依存関係とパッケージ管理を行うことで、大規模なプロジェクトでも効率的に開発を進めることが可能となっています。

まとめ

Go言語の開発には、モジュールの概念とそれを管理するためのgo mod initコマンドが不可欠です。これはGoがコンパイル言語であること、そしてパッケージの依存関係管理が重要であることから来ています。Pythonとは異なり、Goではコードの組織化と管理が言語自体に組み込まれています。これにより、大規模なプロジェクトでも効率的に開発を進めることが可能です。

48
24
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
48
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?