Go/パッケージ

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

このページでは、Goのパッケージに関する構文と意味を解説しています。 標準パッケージライブラリーについては、Go/標準ライブラリーを参照してください。

パッケージ[編集]

式(An expression)は、 Goプログラムは、パッケージ(Packages)をリンクして構築されます。パッケージは、そのパッケージに属する定数、型、変数、関数を宣言した1つまたは複数のソースファイルから構成されます。これらの要素は、エクスポートして別のパッケージで使用することができます[1]

ソースファイルの構成[編集]

ソースファイルの構成(Source file organization)

各ソースファイルは、所属するパッケージを定義するパッケージ節、使用するパッケージを宣言するimport宣言(空の場合もある)、関数、型、変数、定数の宣言(空の場合もある)から構成されています[2]

構文
SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } ;

パッケージ節[編集]

パッケージ節(Package clause;PackageClause)は、各ソースファイルの先頭にあり、そのファイルが属するパッケージを定義します[3]

PackageNameは、ブランク識別子であってはなりません。

package math

同じPackageName(パッケージ名)を持つファイルの集合が、パッケージの実装となります。パッケージの実装では、パッケージのすべてのソースファイルが同じディレクトリに存在することが要求される場合があります。

インポート宣言[編集]

インポート宣言(Import declarations)とは、その宣言を含むソース・ファイルが、インポートされたパッケージの機能(§プログラムの初期化と実行)に依存し、そのパッケージのエクスポートされた識別子へのアクセスを可能にすることを意味します。インポートには、アクセスに使用する識別子(PackageName)と、インポートするパッケージを指定するImportPathが指定されます[4]

構文
ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) ;
ImportSpec       = [ "." | PackageName ] ImportPath ; 
ImportPath       = string_lit ;

PackageNameは、インポートするソースファイル内のパッケージのエクスポートされた識別子にアクセスするための修飾識別子として使用されます。これは、ファイルブロックで宣言されています。PackageNameが省略された場合は、インポートされたパッケージのpackage節で指定された識別子がデフォルトとなります。名前の代わりに明示的なピリオド(.)が現れた場合、そのパッケージのpackage節で宣言された全てのパッケージのエクスポートされた識別子は、インポート元ファイルのfile節で宣言され、修飾子なしでアクセスしなければなりません。

ImportPathの解釈は実装に依存しますが、通常はコンパイルされたパッケージの完全なファイル名の部分文字列であり、インストールされたパッケージのリポジトリへの相対パスかもしれません。

実装上の制限。コンパイラは、ImportPathを、UnicodeのL、M、N、P、Sの一般カテゴリに属する文字(スペースを含まないグラフィック文字)のみを使用した空でない文字列に制限することができます。また、文字 !"#$%&'()*,:;<=>?[\]^`{|} および Unicode の置換文字 U+FFFD を除外することもできます。

関数Sinをエクスポートするパッケージ節package mathを含むパッケージをコンパイルし、コンパイルしたパッケージを「lib/math」で識別されるファイルにインストールしたとします。次の表は、さまざまなタイプのインポート宣言の後にパッケージをインポートするファイルで、Sinにどのようにアクセスするかを示しています。

インポート宣言 Sin のローカル名
import "lib/math" math.Sin
import m "lib/math" m.Sin
import . "lib/math" Sin

インポート宣言は、インポートするパッケージとインポートされるパッケージの間に依存関係を宣言します。パッケージが自分自身を直接または間接的にインポートしたり、エクスポートされた識別子を参照せずにパッケージを直接インポートすることは違法です。副作用(初期化)のみを目的としてパッケージをインポートする場合は、空白の識別子を明示的なパッケージ名として使用します。

import _ "lib/math"

パッケージの例[編集]

以下は、同時進行の素数ふるいを実装した完全なGoパッケージです[5]

package main

import "fmt"

// Send the sequence 2, 3, 4, … to channel 'ch'.
func generate(ch chan<- int) {
	for i := 2; ; i++ {
		ch <- i // Send 'i' to channel 'ch'.
	}
}

// Copy the values from channel 'src' to channel 'dst',
// removing those divisible by 'prime'.
func filter(src <-chan int, dst chan<- int, prime int) {
	for i := range src { // Loop over values received from 'src'.
		if i%prime != 0 {
			dst <- i // Send 'i' to channel 'dst'.
		}
	}
}

// The prime sieve: Daisy-chain filter processes together.
func sieve() {
	ch := make(chan int) // Create a new channel.
	go generate(ch)      // Start generate() as a subprocess.
	for {
		prime := <-ch
		fmt.Print(prime, "\n")
		ch1 := make(chan int)
		go filter(ch, ch1, prime)
		ch = ch1
	}
}

func main() {
	sieve()
}

脚註[編集]

  1. ^ “Packages¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Packages. 
  2. ^ “Source file organization¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Source_file_organization. 
  3. ^ “Package clause¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Package_clause. 
  4. ^ “Import_declarations¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Import_declarations. 
  5. ^ “An example package¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#An_example_package.