挨拶
最近Goで仕事してますが抽象化の方法がようわからんのでぼちぼち調べている感じ。
インタフェース・構造体・埋込
Goの基本的な抽象化機構としてはまあこの辺ですよね。
インタフェースといろんな実装型を定義してロジックに渡してみる例。
https://goplay.space/#SWC6a5AjSqy
インタフェースと構造体の埋め込みの例。Goは継承なしオブジェクト指向スタイルだそう。
親から子は見えないけど子から親は見えるので、親のフィールドは見えるし関数も呼べる。
https://goplay.space/#5wCOnPZv2i6
インタフェースで型を隠蔽する例。インタフェースだとメソッドを呼ぶ以外の操作ができなくなる。
https://goplay.space/#hzhrlUoptug
構造体といえば、型として定義した構造体と無名の構造体は可換(なんかに使える?)。ただし:=で単に代入したときは無名の構造体のままなのでメソッドは呼べない。
https://goplay.space/#_IyBl66MGSw
まあ非公開のフィールドがある場合、パッケージ外から見えないので可換とは言えないかも。
パッケージ
名前空間を分けるための唯一のもの。
https://tour.golang.org/basics/1
グローバル変数、というかパッケージローカルな変数も定義できる。
https://play.golang.org/p/i6rbIoiHFJL
しかしパッケージ内に定義されたものは全部見えて(特に定数と変数が見えるのがつらい)空間がゆるすぎる。
あと構造体にどんなメソッドがあるか調べるにはファイル全部みないといけないのとかつらい。
ソースの頭にパッケージ名を書けるが、実質的にはディレクトリ名で参照するので、あれは意味あるのでしょうか。
同じディレクトリに複数のパッケージ名を置けないわりにプログラムのエントリーポイントはmainパッケージのmain関数になるとかもよくわからない仕様。
クロージャ
関数を返す関数を作って状態を保持・隠蔽できる。
https://goplay.space/#y5QneyUbs6c
関数型変数
Mat Ryerの記事だけど、抽象化の対象が関数1個で十分なら関数型使ったらいいという話。
https://medium.com/@matryer/tiny-abstractions-using-functions-in-go-39cd7b9a1db2
Type switches
interface{}(Cでいう*voidみたいなもの)を受け取り、実際の型で判定して処理を分けるやつ。
https://tour.golang.org/methods/16
複数の型を代入したり関数で受け取ったりできる。
もうちょっと型の範囲を限定できたらいい気がするんだけど、インタフェースでしぼるしかない。
https://goplay.space/#VgfzZQ9snUw