20210605のGoに関する記事は2件です。

【GoのDIライブラリ】wire入門

wireとはDI(依存性注入)によるコンポーネントの接続を自動で初期化してくれるコード生成ツールです 今回はHello Worldを出力するだけのシンプルなアプリケーションを、wireを使わない場合と使った場合の両方作成して比較していきたいと思います! インストール $ go get github.com/google/wire/cmd/wire wireを使わない場合 // main.go type Message string type Greeter struct { Message Message } type Event struct { Greeter Greeter } func NewMessage() Message { return Message("Hello World") } func NewGreeter(m Message) Greeter { return Greeter{ Message: m, } } func NewEvent(g Greeter) Event { return Event{ Greeter: g, } } func (g Greeter) Greet() Message { return g.Message } func (e Event) Start() { msg := e.Greeter.Greet() fmt.Println(msg) } func main() { // 初期化処理 message := NewMessage() greeter := NewGreeter(message) event := NewEvent(greeter) event.Start() } ターミナルでrunコマンドを打ってみるとHello Worldが返ってくることが確認できると思います $ go run main.go Hello World wireを使う場合 まずはmain.goのmain関数の中身を以下のように書き換えましょう func main() { e := InitializeEvent() e.Start() } 次に、wire.goを作成します // wire.go func InitializeEvent() Event { wire.Build( NewEvent, NewGreeter, NewMessage, ) return Event{} } これで準備は整いました。それではターミナルで以下コマンドを打ってみましょう $ wire するとwire_gen.goファイルが自動生成され、(wireを使わない場合にmain関数内で手動で書いていた処理と同等の)初期化処理が記入された関数が自動生成されているはずです! // Code generated by Wire. DO NOT EDIT. //go:generate go run github.com/google/wire/cmd/wire //+build !wireinject package main // Injectors from wire.go: func InitializeEvent() Event { message := NewMessage() greeter := NewGreeter(message) event := NewEvent(greeter) return event } 今回はシンプルなアプリケーションなので初期化処理を自ら書いてもさほど苦痛ではありませんが、もっと複雑なコンポーネントの場合、wireを用いた初期化処理の自動生成がいかに便利か想像がつくと思います 終わりに 今回wireを使わない場合と使う場合の両方を実装して試してみましたが、wireを使うことで初期化処理がとても簡単に行えることがわかりました 今後はwireの恩恵を受けて開発していきたいと思います!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golang で struct を embed する際の注意点

TL;DR embed する際に型を指定した場合としていない場合で、フィールドへの参照の仕方が異なる。 struct を embed する Go には継承という概念はないが、その代替手段として embed(埋め込み)という手段がよく使われる。struct の場合、 embed は下記のようになる。 type Person struct { Name string Age int } type Account struct { Person Field1 string Field2 string } この場合、Account の Person.Name フィールドへのアクセスは、Account.Name のような形でできる。(Account.Person.Name としなくてよい) 型を指定して struct を embed する しかし、型を指定して下記のように定義した場合は、Account.Person.Name としなくてはならない。 type Person struct { Name string Age int } type Account struct { Person Person // 型指定 Field1 string Field2 string } サンプルコード main.go package main import "fmt" type Person struct { Name string Age int } // 型指定なし type Foo struct { Person Field1 string Field2 string } // 型指定あり type Bar struct { Person Person Field1 string Field2 string } func main() { foo := Foo{ Person{"型指定なし", 10}, "a", "b", } bar := Bar{ Person{"型指定あり", 20}, "a", "b", } fmt.Println(foo) // {{型指定なし 10} a b} fmt.Println(bar) // {{型指定あり 20} a b} fmt.Println(foo.Name) // 型指定なし fmt.Println(bar.Name) // bar.Name undefined (type Bar has no field or method X) }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む