Go パッケージの作成とインポート

GolangGolangBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

前のセクションでは、次のコード行を含む基本的なGoプログラムを作成しました。

package main
import "fmt"

これらの2行のコードをどのように理解すればよいでしょうか。また、packageimport文を効果的に使うにはどうすればよいでしょうか。

この実験では、Goでパッケージを作成してインポートする方法を学びます。これにより、コードを再利用可能なモジュールに整理して、Goプロジェクトをより保守しやすく拡張可能にすることができます。

ポイント

  • パッケージの定義と宣言
  • エクスポートされた(公開)識別子とエクスポートされていない(非公開)識別子の理解
  • パッケージのインポートのさまざまな形式:単一、グループ化、ドット、エイリアス、および匿名インポート

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/FunctionsandControlFlowGroup(["Functions and Control Flow"]) go(("Golang")) -.-> go/AdvancedTopicsGroup(["Advanced Topics"]) go(("Golang")) -.-> go/BasicsGroup(["Basics"]) go/BasicsGroup -.-> go/variables("Variables") go/FunctionsandControlFlowGroup -.-> go/functions("Functions") go/AdvancedTopicsGroup -.-> go/time("Time") subgraph Lab Skills go/variables -.-> lab-149064{{"Go パッケージの作成とインポート"}} go/functions -.-> lab-149064{{"Go パッケージの作成とインポート"}} go/time -.-> lab-149064{{"Go パッケージの作成とインポート"}} end

パッケージの宣言と定義

Goにおけるパッケージは、PythonのモジュールやCのライブラリに似ています。コードを整理して再利用するために使用されるソースコードファイルのコレクションです。すべてのGoファイルは、ファイルの先頭でパッケージを宣言する必要があります。

: Goプログラムは、実行のエントリポイントとして機能するmainという名前の1つだけのパッケージを持たなければなりません。それがなければ、プログラムは実行可能ファイルを生成できません。

ポイント

  1. エクスポートされた(公開)識別子大文字で始まる識別子(変数、関数、型など)は、他のパッケージからアクセスできます。これらは、パッケージの公開インターフェイスと考えられます。
  2. エクスポートされていない(非公開)識別子小文字で始まる識別子は、同じパッケージ内でのみアクセスできます。これらは、パッケージの内部実装の詳細と考えられます。
  3. パッケージの凝集性:同じフォルダ内のすべてのファイルは、同じパッケージに属する必要があります。これにより、関連するコードがまとまったままになります。
  4. パッケージの命名規則:パッケージ名は、小文字で、短く、説明的で、アンダースコアや大文字を避ける必要があります。

独自のカスタムパッケージを作成しましょう。

  1. propagandistという名前のフォルダを作成し、その中にpropagandist.goというファイルを作成します。

    mkdir ~/project/propagandist
    touch ~/project/propagandist/propagandist.go
  2. propagandist.goに次のコードを記述します。

    package propagandist
    
    var Shout = "I Love LabEx" // 公開変数
    var secret = "I love the dress" // 非公開変数
    
    func Hit() string {
        return "Don't hit me, please!"
    }
    • Shout公開で、大文字で始まるため、propagandistをインポートする他のパッケージからアクセスできます。
    • secret非公開で、小文字で始まるため、propagandistパッケージ内でのみ使用できます。
    • Hit公開関数で、他のパッケージからアクセスできます。
  3. パッケージ用のGoモジュールを初期化します。

    cd ~/project/propagandist
    go mod init propagandist

    このコマンドは、propagandistディレクトリに新しいGoモジュールを初期化し、パッケージの依存関係を管理するのに役立ちます。

単一のパッケージのインポート

propagandistパッケージを使用するには、新しいGoプログラムを作成しましょう。この手順では、Goコードで単一のパッケージをインポートして使用する方法を示します。

  1. プロジェクトフォルダに新しいGoファイルpacExercise.goを作成します。

    touch ~/project/pacExercise.go
  2. プログラム用のGoモジュールを初期化します。

    cd ~/project
    go mod init pacExercise
  3. go.modファイルを更新して、ローカルパッケージの依存関係を追加します。ターミナルで次のコマンドを実行します。

    echo "replace propagandist =>./propagandist" >> go.mod

    重要: このコマンドは、go.modファイルにreplaceディレクティブを追加します。これは重要です。なぜなら、これによりGoに対して、propagandistパッケージをリモートリポジトリからダウンロードしようとせずに、ローカルディレクトリ./propagandistからソースを取得するように指示するからです。このコマンドをターミナルで実行すると、go.modファイルにreplace propagandist =>./propagandistの行が追加されます。直接この行をファイルに手動で書き込まないでください。

  4. pacExercise.goに次のコードを書いて、propagandistパッケージをインポートして使用します。

    package main
    
    import (
        "fmt"
        "propagandist"
    )
    
    func main() {
        fmt.Println(propagandist.Shout) // 公開変数にアクセス
    }
    • このコードは、出力を表示するためのfmtパッケージとpropagandistパッケージをインポートします。
    • その後、propagandist.Shoutを使用してpropagandistパッケージから公開変数Shoutにアクセスします。
  5. プログラムを実行します。

    go mod tidy
    go run pacExercise.go

    go mod tidyコマンドは、新しい依存関係でgo.modファイルを更新することを確認します。go run pacExercise.goコマンドは、プログラムをコンパイルして実行します。

    予想される出力:

    I Love LabEx

グループ化されたインポート

複数のパッケージをインポートする際には、読みやすさと整理のためにグループ化されたインポートを使用できます。これはスタイルに関する選択事項であり、コードの機能には影響しません。

  1. pacExercise.goを変更して、グループ化されたインポートを使用します。

    package main
    
    import (
        "fmt"
        "propagandist"
    )
    
    func main() {
        fmt.Println(propagandist.Shout)
    }

    上のコードスニペットでは、fmtpropagandistの各パッケージが、丸括弧で囲まれた単一のimportブロック内にインポートされています。これにより、複数のパッケージのインポートを読みやすく管理しやすくなります。これは、前の例とまったく同じであり、グループ化されたインポート構文の使い方を示しています。

  2. プログラムを実行して、依然として機能することを確認します。

    go run pacExercise.go

    プログラムはエラーなく実行され、以前と同じ結果が出力されるはずです。

ドットインポート

ドットインポートを使用すると、関数や変数を呼び出す際にパッケージ名の接頭辞を省略できます。名前空間の競合を引き起こし、読みやすさを低下させる可能性があるため、明示的なパッケージ名を推奨することが多いです。ただし、それが何であるかを知っておくのは良いでしょう。

  1. pacExercise.goを変更して、fmtに対してドットインポートを使用します。

    package main
    
    import. "fmt"
    import "propagandist"
    
    func main() {
        Println(propagandist.Shout) // `fmt.` 接頭辞は不要
    }
  • ここで、import. "fmt"は、fmtパッケージの関数や変数をfmt.接頭辞なしで直接使用できることを意味します。
  • たとえば、fmt.Printlnの代わりにPrintlnを使用します。
  1. プログラムを実行します。

    go run pacExercise.go

    予想される出力:

    I Love LabEx

エイリアスインポート

2つのパッケージが似た名前を持っている場合、明確さを保つためまたは競合を回避するために、インポートされたパッケージにエイリアスを付けることができます。これは、コードの読みやすさを向上させ、名前空間の衝突を管理するのに役立ちます。

  1. pacExercise.goを変更して、fmtioとしてエイリアス付けします。

    package main
    
    import io "fmt"
    import "propagandist"
    
    func main() {
        io.Println(propagandist.Shout) // `fmt`の代わりにエイリアス`io`を使用
    }
    • import io "fmt"は、fmtパッケージに対してエイリアスioを作成します。
    • これで、fmt.Printlnの代わりにio.Printlnを使用します。
  2. プログラムを実行します。

    go run pacExercise.go

匿名インポート

匿名インポートは、副作用のためにパッケージをインポートするために使用されます。たとえば、そのinit()関数を実行するために、そのエクスポートされた識別子のいずれかを直接参照する必要がない場合です。これは、ドライバを登録するパッケージやその他の初期化タスクを実行するパッケージに役立ちます。

  1. pacExercise.goを変更して、timeの匿名インポートを含めます。

    package main
    
    import (
        "fmt"
        "propagandist"
        _ "time" // 匿名インポート
    )
    
    func main() {
        fmt.Println(propagandist.Shout)
    }
    • import _ "time"は匿名インポートです。アンダースコア_はブランク識別子として使用され、コンパイラに対して、副作用のためにパッケージをインポートしており、コード内でそれから直接何も参照しないことを伝えます。
    • このプログラムが実行されるとき、timeパッケージのinit()関数が実行されます。ここではtimeパッケージには特に目に見える副作用はありませんが、多くのパッケージではこれを使用してデータベースドライバや構成設定を登録しています。
  2. プログラムを実行します。

    go run pacExercise.go

    予想される出力:

    I Love LabEx

まとめ

この実験では、以下のことを学びました。

  1. Go言語でカスタムパッケージを作成して定義し、再利用可能なコードをカプセル化する方法
  2. 公開(エクスポート)された識別子と非公開(エクスポートされていない)識別子の違いと、それがアクセシビリティに与える影響
  3. パッケージをインポートするさまざまな方法とそのそれぞれの使用例
    • 単項目インポート:1回に1つのパッケージをインポートする
    • グループ化されたインポート:整理をよくするために1つのブロックで複数のパッケージをインポートする
    • ドットインポート:パッケージ名の接頭辞なしで直接その識別子を使用してパッケージをインポートする(注意して使用)
    • エイリアスインポート:読みやすさを向上させるか、または名前の競合を回避するためにインポートされたパッケージを改名する
    • 匿名インポート:初期化などの副作用のためだけにパッケージをインポートする
  4. パッケージ内のinit()関数の役割と、匿名インポートがその実行をトリガーする方法

この実験を完了することで、パッケージを使ってGoプロジェクトを効果的に構造化して管理できるようになりました。再利用可能なモジュールを作成し、識別子へのアクセスを制御し、コードをより整理して、より保守可能で拡張可能なGoアプリケーションを作成できます。