kakts-log

programming について調べたことを整理していきます

golang Packageまわりの整理

golangいじりはじめました。早速チュートリアルを一通りやっていて、パッケージのインポートについてちゃんと整理したかったので以下のページを軽く和訳しつつまとめます。
http://www.golang-book.com/11/index.htm

以下和訳

Packages

Goは良質なソフトウェアエンジニアリングの実践を促すためにデザインされました。高品質なソフトウェアにとって重要な点は、"Don't Repeat Yourself"という原則に表現されたコードの再利用にあります。

 チャプター7で扱った関数は、我々がコードの再利用を可能にする第一の層です。Goはコード再利用のための他の機構も提供しています:パッケージです。我々が遭遇するプログラムのほぼすべてが以下の行でインクルードされます

import "fmt"

fmt はフォーマットや、スクリーンへの出力に関係するいくつかの関数を含んだパッケージ名です。コードをこのようにバンドルすることは3つの理由による物です

1: importは名前のオーバーラップをする機会を減らします。これは私たちの関数名を短く簡潔に保つ。

2: コードを組織化してまとめるので、再利用したいコードを簡単に探すことが出来る

3: 小さなプログラムのチャンクの再コンパイルを要請することによって、コンパイラーの処理の高速化が可能になる。 我々はfmtパッケージを使うが、プログラムを返るたびに毎回再コンパイルする必要がない。

Creating Packages

パッケージというのは、それを使う分割されているプログラムがあるコンテキストにおいてのみ真に効果があるものです。? 分割されたプログラムが無い場合、我々はパッケージ使う方法をもちえません。これから自分たちで書いたパッケージを使ったアプリケーションを作ってみましょう。 

~/Go/src/golang-book/chapter11
でmain.goを作りましょう。 内容は以下になります。



package main

import "fmt" # fmtパッケージインポート
import "golang-book/chapter11/math"

func main() {
    xs := float64{1, 2, 3, 4}
    avg := math.Average(xs)
    fmt.Println(avg)
}

ここでchapter11の中に上でimportした部分に書いてあるものと同じ要領でmathというフォルダを作りましょう。このフォルダの中にmath.goをつくり、以下の内容で作ります。

package main

func Average(xs float64) float64 {
    total := float64(0)
    for _, x := range xs {
        total += x
    }
    return total / float64(len(xs))
}

ターミナルを使って、mathフォルダに移動し、 go install を実行してください。このコマンドによって math.go をコンパイルして、リンク可能なオブジェクトファイルを
 ~/Go/pkg/os_arch/golang-book/chapter11/math.a ( 'os'と書かれたところは 'windows'などに置き換えられ、'arch' は 'amd64' など、環境に合わせて置き換えられます)

ここでchapter11フォルダに戻り、 go run main.go コマンドを実行してください。そしてchapter2.5の項目を読んでください。いくつか注意点があります

・ mathはGoの標準ディストリビューションの中のパッケージ名です。しかし、Goパッケージは階層で分類することができるので、自分で作成した同名のパッケージを安全に使うことができます。(実際の標準パッケージのmathは "math"とそのまま表しますが、今回作った物は"golang-book/chapter11/math"と表します)

・自分たちでつくったmathライブラリを import "golang-book/chapter11/math"とインポートする時、math.goの内部ではフルパスの最後の部分だけを使って、
package math
としています

・自分で作ったパッケージライブラリからmathの関数を参照する時、フルパスでなく短縮名のmathを使います。もし同じプログラム内で標準のものと自作のmathを使う時、エイリアスを使うことが出来ます
import m "golang-book/chapter11/math"
func main() {

    xs := []float64{1, 2, 3, 4}
    avg := m.Average(xs)
    fmt.Println(avg)
}

・パッケージ内での関数名が大文字で始まっていることに気づいたかもしれません。Goでは、大文字で始まる関数は、他のパッケージから利用できるということを意味します。
もしさきほどの関数をAverageでなくaverageと命名したら、mainプログラムではそれを利用することが出来ません。

他のパッケージから呼び出してもらいたい関数だけを大文字で命名し、それ以外は隠蔽してしまうことは良い慣習です。これは作成した後に他のプログラムを破壊することを心配すること無く変更を行うことを促し、パッケージを使いやすくします。

・パッケージ名はそれが書かれてるフォルダーにマッチします。マッチする方法はいろいろありますが、同様の階層にしておくのがより簡単でしょう。