ソース コード ファイルは特定のパッケージに属している必要があり、ソース コード ファイル内の有効なコードの最初の行は、パッケージが含まれるパッケージを宣言するpackage pacakgeName
ステートメントである必要があります。
パッケージの基本概念
Go 言語のパッケージは、ディレクトリ ツリーの編成形式を使用します。一般に、パッケージの名前は、そのソース ファイルが配置されているディレクトリの名前になります。ただし、Go 言語では、パッケージ名がパッケージ名と同じである必要はありません。構造が明確になるように、パッケージ名とディレクトリ名は同じ名前にすることをお勧めします。
パッケージは非常に深いディレクトリに定義でき、パッケージ名の定義にはディレクトリ パスは含まれませんが、パッケージは通常、参照されるときに絶対パス参照を使用します。たとえば、 GOPATH/src/a/b/
の下にパッケージ c を定義します。パッケージ c のソースコードでは、 package a/b/c
ではなくpackage c
として宣言するだけですが、パッケージ c をインポートする場合は、 import "a/b/c"
のようにパスを持ってくる必要があります。
パッケージのイディオム:
- パッケージ名は通常小文字で、短くて意味のある名前を使用します。
- 一般に、パッケージ名は、パッケージが配置されているディレクトリの名前と同じである必要がありますが、異なる場合もあります。パッケージ名には、
-
などの特殊記号を含めることはできません。 - パッケージは通常、ドメイン名をディレクトリ名として使用するため、パッケージ名の一意性が保証されます。たとえば、GitHub プロジェクトのパッケージは、通常
GOPATH/src/github.com/userName/projectName
ディレクトリに配置されます。 - main という名前のパッケージはアプリケーションのエントリ パッケージであり、メイン パッケージが含まれていないソース コード ファイルをコンパイルしても実行可能ファイルは取得されません。
- フォルダー内のすべてのソース コード ファイルは同じパッケージにのみ属することができ、同じパッケージに属するソース コード ファイルを複数のフォルダーに配置することはできません。
パッケージのインポート
コード内で他のパッケージの内容を参照するには、import キーワードを使用して使用するパッケージをインポートする必要があります。具体的な構文は次のとおりです。
import “path”
予防:
- import ステートメントは通常、ソース コード ファイルの先頭のパッケージ宣言ステートメントの下に配置されます。
- インポートされたパッケージ名は二重引用符で囲む必要があります。
- パッケージ名は
GOPATH/src/
から計算され、/
で区切られます。
パッケージのインポートを記述するには、単一行インポートと複数行インポートという 2 つの方法があります。
単一行インポート
単一行インポートの形式は次のとおりです。
import “包 1 的路径”
import “包 2 的路径”
複数行インポート
複数行のインポートの形式は次のとおりです。
import (
“パッケージ 1 へのパス”
“パッケージ 2 へのパス”
)
パッケージのインポートパス
パッケージの参照パスの書き方にはフルパスインポートと相対パスインポートの2通りがあります。
フルパスインポート
パッケージの絶対パスは、次のようにGOROOT/src/
またはGOPATH/src/
の後のパンのストレージ パスです。
import “lab/test”
import “database/sql/driver”
import “database/sql”
上記のコードの意味は次のとおりです。
- テスト パッケージはカスタム パッケージであり、そのソース コードは
GOPATH/src/lab/test
ディレクトリにあります。 - ドライバー パッケージのソース コードは
GOROOT/src/database/sql/driver
ディレクトリにあります。 - SQL パッケージのソース コードは
GOROOT/src/database/sql
ディレクトリにあります。
相対パスインポート
相対パスはGOPATH
の下にパッケージをインポートする場合にのみ使用でき、標準パッケージは完全パスを使用してのみインポートできます。
たとえば、パッケージ a のパスはGOPATH/src/lab/a
、パッケージ b のパスはGOPATH/src/lab/b
であり、パッケージ a をパッケージ b にインポートする場合、相対パス インポート方法を使用できます。例は次のとおりです。
// 相对路径导入
import “../a”
もちろん、以下に示すように、上記のフルパスインポートを使用することもできます。
// 全路径导入
import “lab/a”
パッケージリファレンスフォーマット
パッケージ参照には 4 つの形式があり、fmt パッケージはこれら 4 つの形式を示す例として使用されます。
1) 標準的な引用形式
import “fmt”
このとき、 fmt.
プレフィックスとして使用して、fmt パッケージ内のメソッドを使用できます。これは一般的に使用されるメソッドです。
サンプルコードは次のとおりです。
package main
import "fmt"
func main() {
fmt.Println("IT基礎")
}
2) カスタムエイリアス参照形式
パッケージをインポートするとき、次のように、インポートされたパッケージのエイリアスを設定することもできます。
import F “fmt”
このうち F は fmt パッケージのエイリアスであり、標準参照形式ではfmt.
の代わりにF.
使用することで、fmt パッケージ内のメソッドをプレフィックスとして使用できます。
サンプルコードは次のとおりです。
package main
import F "fmt"
func main() {
F.Println("IT基礎")
}
3) 引用の書式設定を省略する
import . “fmt”
この形式は、fmt パッケージを現在のプログラムに直接マージすることと同等であり、fmt パッケージ内のメソッドを使用する場合、接頭辞fmt.
を追加せずに直接引用できます。
サンプルコードは次のとおりです。
package main
import . "fmt"
func main() {
//Prefix fmtは必要ありません。
Println("IT基礎")
}
4) 匿名参照形式
パッケージを参照するときに、パッケージ内のデータを使用せずにパッケージ初期化の init 関数だけを実行したい場合は、次のように匿名参照形式を使用できます。
import _ “fmt”
匿名でインポートされたパッケージは、他の方法でインポートされたパッケージと同様に、実行可能ファイルにコンパイルされます。
パッケージが標準形式を使用して参照されているが、そのパッケージがコード内で使用されていない場合、コンパイラはエラーを報告します。パッケージ内に init 初期化関数がある場合、 import _ "パッケージ へのパス"
でパッケージが参照され、パッケージの初期化関数のみが実行されます。パッケージに init 初期化関数がない場合でも、コンパイラはエラーは報告されません。
サンプルコードは次のとおりです。
package main
import (
_ "database/sql"
"fmt"
)
func main() {
fmt.Println("IT基礎")
}
知らせ:
- パッケージには複数の init 関数を含めることができ、パッケージのロード時にすべての init 関数が実行されますが、実行順序は保証されないため、複数の init 関数をパッケージに配置し、必要なロジックを配置することはお勧めできません。で 1 つの init 関数に初期化されます。
- パッケージには循環参照を含めることはできません。たとえば、パッケージ a はパッケージ b を参照し、パッケージ b はパッケージ c を参照します。パッケージ c もパッケージ a を参照すると、コンパイルは失敗します。
- パッケージへの繰り返しの参照は許可されています。たとえば、パッケージ a はパッケージ b と c を参照し、パッケージ b と c は両方ともパッケージ d を参照します。このシナリオは d を繰り返し参照することと同等であり、これは許可されており、Go コンパイラーはパッケージ d の init 関数が 1 回だけ実行されることを保証します。
これまでの一連の学習を通じて、Go プログラムの起動とロードのプロセスについては大体理解できたと思いますが、Go ブートローダーは、メイン パッケージの mian 関数を実行する前に、まずプログラム全体のパッケージを初期化します。実行プロセス全体を次の図に示します。
Go 言語パッケージの初期化には次の特徴があります。
- パッケージ初期化子は、main 関数によって参照されるパッケージから開始し、他のパッケージを参照しないパッケージが見つかるまで段階的にパッケージ参照を検索し、最終的にパッケージ参照の有向非巡回グラフを生成します。
- Go コンパイラーは DAG をツリーに変換し、ツリーのリーフ ノードから開始してレイヤーごとにパッケージを初期化します。
- 単一パッケージの初期化プロセスは上の図に示されており、最初に定数を初期化し、次にグローバル変数を初期化し、最後にパッケージの init 関数を実行します。