ソースファイルの構成(''Source file organization'')
各ソースファイルは、所属するパッケージを定義するパッケージ節、使用するパッケージを宣言するimport宣言（空の場合もある）、関数、型、変数、定数の宣言（空の場合もある）から構成されています。
構文:
SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } ;
パッケージ節(''Package clause'';PackageClause)は、各ソースファイルの先頭にあり、そのファイルが属するパッケージを定義します。
PackageNameは、ブランク識別子であってはなりません。
例:
package math
同じPackageName（パッケージ名）を持つファイルの集合が、パッケージの実装となります。パッケージの実装では、パッケージのすべてのソースファイルが同じディレクトリに存在することが要求される場合があります。
インポート宣言(Import declarations)とは、その宣言を含むソース・ファイルが、インポートされたパッケージの機能(§プログラムの初期化と実行)に依存し、そのパッケージのエクスポートされた識別子へのアクセスを可能にすることを意味します。インポートには、アクセスに使用する識別子(PackageName)と、インポートするパッケージを指定するImportPathが指定されます。
構文:
ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) ;
ImportSpec       = [ "." | PackageName ] ImportPath ; 
ImportPath       = string_lit ;
PackageNameは、インポートするソースファイル内のパッケージのエクスポートされた識別子にアクセスするための修飾識別子として使用されます。これは、ファイルブロックで宣言されています。PackageNameが省略された場合は、インポートされたパッケージのpackage節で指定された識別子がデフォルトとなります。名前の代わりに明示的なピリオド(.)が現れた場合、そのパッケージのpackage節で宣言された全てのパッケージのエクスポートされた識別子は、インポート元ファイルのfile節で宣言され、修飾子なしでアクセスしなければなりません。
ImportPathの解釈は実装に依存しますが、通常はコンパイルされたパッケージの完全なファイル名の部分文字列であり、インストールされたパッケージのリポジトリへの相対パスかもしれません。
実装上の制限。コンパイラは、ImportPathを、UnicodeのL、M、N、P、Sの一般カテゴリに属する文字（スペースを含まないグラフィック文字）のみを使用した空でない文字列に制限することができます。また、文字 !"#$%&'()*,:;<=>?[\]^`
インポート宣言は、インポートするパッケージとインポートされるパッケージの間に依存関係を宣言します。パッケージが自分自身を直接または間接的にインポートしたり、エクスポートされた識別子を参照せずにパッケージを直接インポートすることは違法です。副作用(初期化)のみを目的としてパッケージをインポートする場合は、空白の識別子を明示的なパッケージ名として使用します。
例:
import _ "lib/math"
以下は、同時進行の素数ふるいを実装した完全なGoパッケージです。
[https://play.golang.org/p/Z-vbYn6dqav 例]:
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()
}