この記事は 東京理科大学 Advent Calendar 2018 1日目の記事です。
続きを読むsortパッケージから学ぶ汎用的なパッケージ作成
Goでソートを行うときにsortパッケージを活用すると思います。Goを使っている人はこのsortパッケージの実装を熟知してから、自分で新規パッケージを作成すると、汎用的に利用できるパッケージを作ることができるはずです。
モチベーション
コーディングインタビューの話ではないが自分が人のコードを読むとしたら「どういうレイヤー/パッケージ構成」にしているか、というのは設計力を測る一つの観点にしています。
続きを読むcoding interviewは好きじゃないけど、やるならこういうの出してみるかな〜ってのを仮で作ってみた。 https://t.co/gP7MkBCkd0
— kaneshin (@kaneshin0120) September 15, 2018
純粋に言語の習熟度とアルゴリズムの実装経験を測れる具合にしている。
サンクスカード from Tully's Coffee
ちょっと席譲っただけだったんですが、後日サンクスカードを店員さんから頂いて、ほっこりした朝でした。
golangでABテストの振る舞いを実装する
golangに限らないんですが、ABテストの振る舞いをちゃんとした設計のもと実装するのって難しいと思っています。
よくあるパターンとしては、Userという構造体があって、それに対してABテストによる振る舞いを変えるように実装をすることかと思います。
User
type User struct { ID int Name string }
関数を生やす
あまり考えずに関数を作っていく方針
func (u User) IsFoo() bool { return u.ID%10 == 0 } func (u User) IsBar() bool { return u.ID%10 == 1 } func main() { u := User{ID: 1, Name: "kaneshin"} fmt.Println(u.IsFoo()) fmt.Println(u.IsBar()) }
コード:https://play.golang.org/p/bSw-EfBJFm
これは、実装自体は簡単で、やりがちなんですが、User構造体が肥大化するのでこの実装は好きじゃないです。
型を新規作成
新しく構造体を定義して、それらがABテストで有効かどうかの振る舞いを実装します。
type ( FooTester User BarTester User ) func (u FooTester) IsEnabled() bool { return u.ID%10 == 0 } func (u BarTester) IsEnabled() bool { return u.ID%10 == 1 } func main() { u := User{ID: 1, Name: "kaneshin"} fmt.Println(FooTester(u).IsEnabled()) fmt.Println(BarTester(u).IsEnabled()) }
コード:https://play.golang.org/p/H_FZKYHX17
これが今のところわかりやすいですかね。必要に応じて下記のような interface を定義することもできます。
type ABTester interface { IsEnabled() bool }
これを書いたキッカケ
go1.8から型の変換がより使える幅が広がったので、何かいい方法無いかなーと考えていたのですが、結果としていい方法は思いつきませんでした。
func example() { type T1 struct { X int `json:"foo"` } type T2 struct { X int `json:"bar"` } var v1 T1 var v2 T2 v1 = T1(v2) // now legal }
タグの変換ができるので、Unmarshal/Marshalやタグを定義してなどのうまい方法は思いきましたが、暗にリフレクションを多用する実装はしたくないな、と。
おわりに
結論はないんですが、ABテストの知見って無いですかね。トレイトとかの案も出ると思いますが、使用する元の情報(e.g.: User.ID)をトレイト先が欲するのは違う。日付判定しかしないトレイトならOKなんですがね。