0
Help us understand the problem. What are the problem?

posted at

updated at

都道府県の型を例にGoで組み込み型を拡張する

ユーザーの都道府県を扱うアプリケーションを作成していたときに、

いままで

prefecture.go
const (
	PrefectureHokkaido   = "hokkaido"
	PrefectureAomori     = "aomori"
    :
)

というような県の定数をstring で宣言していていた。
この場合はUIに返すときには日本語に変換する必要があり愚直にmapを定義して変換していた。

prefecture.go
var prefectureToJpName = map[string]string{
	"hokkaido":  "北海道",
	"aomori":    "青森県",
	"iwate":     "岩手県",
    :
}

致命的な問題はなかったのだが、

  • コードの量が増える
  • 関連のあるものなのにコードが散らばってしまう

などの課題があった。

組み込み型として扱う

prefecture.go
type Prefecture string 

const (
	Hokkaido Prefecture  = "hokkaido"
	Aomori   Prefecture  = "aomori"
    :
)

上記のように型定義を行うことで一見変わらないように見えるが、組み込み関数を定義することができる。

つまり、いままでmap型で独立して存在していた日本語変換が

prefecture.go
func (p Prefecture) ToJapanese() string {
  switch s {
    case Hokkaido:
        return "北海道"
    case Aomori:
        return "青森"
              :
  }
}

というように拡張することができる。
Prefecture自体の実体はstring だが、ToJapanese という日本語変換の組み込み関数を持つ型になっている。

さらにこのように型を定義することによってさらに拡張ができるようになる。
例えば、県から県の所在グループを取得したいとなったときに、

prefecture.go
      :
type PrefectureGroup

const (
  Hokkaido PrefectureGroup = "hokkaido"
  Tohoku PrefectureGroup = "tohoku"
  Kanto PrefectureGroup = "kanto"
      :
)

func (p Prefecture) GetGroup() PrefectureGroup {
  switch p {
    case Hokkaido:
        return "hokkaido"
    case Aomori, Iwate, Miyagi, Akita, Yamagata, Fukushima:
        return "tohoku"
               :
  }
}

というように拡張することができる。
PrefectureGroupも同様にToJpanaese などと拡張することもできる。

このように型として定義し、組み込み型で拡張することで
課題であった

  • コードの量が増える
  • 関連のあるものなのにコードが散らばってしまう

を解決でき、アプリケーションコードの見通しが良くなる。
なにより良いところはこのようなコードの書き方がより Goらしい ということだ。(Goらしいことでなにが嬉しいかというのは参考にもある実用Goにかかれています。)

補足

実際にプロダクトで都道府県を扱うとなると、
構造体として日本語なども格納しておくとより楽に扱えて良い。
https://github.com/diverse-inc/jp_prefecture
このリポジトリのように実装するのがベストに近い気がする。

参考

このtips は実用 Go言語 ―システム開発の現場で知っておきたいアドバイス 2.2.1 「メソッドを追加して組み込み型を拡張する」を参考に自分の体験を踏まえて書きました。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?