GoでSingletonぽいことを実現する、とある方法 | おそらくはそれさえも平凡な日々¶
チェック¶
- [ ] 本文を確認した
- [ ] 概要を確認した
- [ ] タグを確認した
- [ ]
inbox/直下へ移行した
概要¶
GoでSingletonぽいことを実現する、とある方法 | おそらくはそれさえも平凡な日々 のWebクリップ。本文からGo、AWS、Observability、設計、キャリア評価などの学習材料として使えそうな内容を保存した。関連タグ: go, go/design, web-clip。
本文¶
おそらくはそれさえも平凡な日々¶
- Go
GoでSingletonぽいことを実現する、とある方法¶
ちなみに今回のコードはそれほど実用性はありません。ここまで頑張って、シングルトンぽいことを実現する必要性は感じられないからです。サンプルコードはこちら。
https://www.github.com/Songmu/go-sandbox/
Goでシングルトンを実現する方法として以下の様なコードが良く見られます。
package singleton import "sync" type singleton struct{ } var ( instance *singleton once sync.Once ) func GetInstance() *singleton{ once.Do(func() { instance = &singleton{} }) return instance }
sync.Once
nil
golint
% golint . singleton/singleton.go:14:20: exported func GetInstance returns unexported type *singleton.singleton, which can be annoying to use
GetInstance
*singleton.singleton
dummyメソッドを持ったinterfaceを使うという解法¶
go/ast
Sum/Union/Variant Type in Go and Static Check Tool of switch-case handling
今回のシングルトンの場合、パッケージ自体はこのようになります。
package singleton import ( "fmt" "strings" "sync" "sync/atomic" ) // Deeeeter implements Deeeet() method type Deeeeter interface { Deeeet() getAge() // as a dmmuy method } type deeeet struct { age int64 // accessed atomically } var ( d Deeeeter o sync.Once ) // GetDeeeter gets the Deeeeter func GetDeeeter() Deeeeter { o.Do(func() { d = &deeeet{} }) return d } // Deeeet desu... func (de *deeeet) Deeeet() { age := int(atomic.AddInt64(&de.age, 1)) fmt.Printf("d%stです…\n", strings.Repeat("e", age)) } func (de *deeeet) getAge() { fmt.Println(de.age) }
これを以下のようなコードで実行してみましょう。
package main import ( "fmt" "./singleton" ) func main() { deeeet := singleton.GetDeeeter() deeeet.Deeeet() deeeet.Deeeet() singleton.GetDeeeter().Deeeet() deeeet.Deeeet() }
これを実行してみると以下のようになります。
GetDeeeeter
Deeeeter
deeeet
https://godoc.org/github.com/Songmu/go-sandbox/singleton にもちゃんとドキュメントが生成されており、ニッコリ。
Deeeet
getAge
type imitateDeeeet struct { } func (ide *imitateDeeeet) Deeeet() { fmt.Println("deeeet(偽)です…") } func (ide *imitateDeeeet) getAge() { fmt.Println("17歳です♥") } // var _ singleton.Deeeeter = &imitateDeeeet{}
imitateDeeeet
% go run singleton.go # command-line-arguments ./singleton.go:29:5: cannot use imitateDeeeet literal (type *imitateDeeeet) as type singleton.Deeeeter in assignment: *imitateDeeeet does not implement singleton.Deeeeter (missing singleton.getAge method) have getAge() want singleton.getAge()
de.age
2019-06-01T18:57:39+0900
要点¶
- Goの実装・設計・標準的な書き方を面接や実務の深掘り材料にする。
- 元URL: https://songmu.jp/riji/entry/2017-10-28-some-singleton-in-golang.html