Cou氏の徒然日記

ほのぼの日記ブログです。

Go言語の学習 その4 (go.modと関数名による関数の公開・非公開定義)

前回は、同一パッケージを複数ソースに分割したケースでしたが、今回はパッケージを分割。

mainパッケージのサブパッケージとしてprintを作成します。

ソース構成はこんな感じですね。

C:.
│  hello.go
│  main.go

└─print
        outmessage.go

ただ、別パッケージであるため、パッケージの関係を明確に定義する必要があります。

 

◆ go.mod によるパッケージの定義

Go言語には、go.mod というファイルがあり、このファイルにモジュールの依存関係が定義されます。

ということで、今回は、test1の下のmain ディレクトリがルートディレクトリになるため、この階層でgo mode init」コマンドを実行。

PS C:\Study\Go\test1\main> go mod init 
go: cannot determine module path for source directory C:\Study\Go\test1\main (outside GOPATH, 
module path must be specified)

Example usage:
        'go mod init example.com/m' to initialize a v0 or v1 module
        'go mod init example.com/m/v2' to initialize a v2 module

Run 'go help mod init' for more information.

引数として指定したものが、そのモジュール群のパッケージ名になるため、

今回は「test1」と指定。

PS C:\Study\Go\test1\main> go mod init test1
go: creating new go.mod: module test1
go: to add module requirements and sums:
        go mod tidy

これで、test1/main 配下のモジュールは「test1」パッケージとgo.modファイルに定義されました。

go.modファイル
module test1

go 1.22.2

 

◆ 内部パッケージクラス作成

続いて、test1の配下の printパッケージのソースの実装。

[outmessage.go]
package print

import "fmt"

func printmessage() {
	fmt.Println("Good Morning.")
}

同様に、適当な標準出力処理を実装します。

出力内容は区別がつくように適当に違うものに。

 

これで main.go からこのprint_messageパッケージをインポートして、printmessage関数を呼び出そうとしますが…

あれ・・・?出てこない・・・?

print パッケージの printmessage 関数がリストに出てこないです。

パッケージのインポート自体はエラーになっていないので問題なさそうなので、「ん?」と思っていました。

 

ここでGo言語の仕様を調べてみると・・・

  • 先頭が小文字の関数: 外部パッケージから呼び出しができない(Private扱い)
  • 先頭が大文字の関数: 外部パッケージから呼び出し可能(Public扱い)

…という仕様があるようです。

 

ということで、関数名の先頭を大文字にしてみると…

[outmessage.go] (修正後)
package print

import "fmt"

func Printmessage() {
	fmt.Println("Good Morning.")
}

確かに、呼び出せるようになりました。

 

この仕様はなかなか画期的ですね。

大文字、小文字という違いでPublic / Privateを定義できるのは面白いなと。

これで、無事に実行でき、printmessageパッケージの関数を呼び出して実行できることが確認できました。