コンテンツにスキップ

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

if instance == nil { instance = &singleton{} }
var instance = &singleton{}

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() }

これを実行してみると以下のようになります。

% go run singleton.go detです… deetです… deeetです… 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

タグ

go #go/design #web-clip