📝
[Go] Defined typeとType alias
Go には、独自の型を定義するのに Defined type (Named type) と 型エイリアス (Type alias) の 2 つの定義方法があります。
かく言う僕は、普段 Defined type しか使わないのもあり、この 2 つの型定義方法の違いを知りませんでした。
今回は、自分用のメモも兼ねて、この 2 つの定義法の違いを記していこうと思います。
Defined type (Named type とも言うらしい)
僕は基本的には普段この Defined type しか使っていません。
// こんな書き方
type DefinedType int
特徴としては下記の認識です。
- プリミティブな型 (上記では
int
) とは全く別の型になる。 - 上記故に型チェックに向いている (
DefinedType
型の変数にint
型の値を代入しようとするとコンパイルエラーが起きる)。 - レシーバの型として定義可能 (メソッドを生やせる)。
- バリデーション用メソッドなどを定義して、ValueObject のように扱える。
型エイリアス (Type alias)
// こんな書き方
type AliasType = int
特徴としては下記の認識です。
- プリミティブ型 (上記では
int
) と同じ型として使用できる。 - 上記故に型チェックに向いていない (
AliasType
型の変数にint
型の値を代入可能)。 - レシーバの型として定義不可能 (メソッドを生やせない)。
違い (コードで)
こでまで述べた Defined type と Alias type の特徴をもとに 2 つの違いをコードでまとめると、下記の感じです。
package main
import "fmt"
type DefinedType int
type AliasType = int
func inclement(a, b int) int {
return a + b
}
func main() {
var d DefinedType = 1
var a AliasType = 1
fmt.Printf("increment result: %d", inclement(d, 2)) // コンパイルエラー
fmt.Printf("increment result: %d", inclement(a, 2)) // 可
n := 1
n = DefinedType(n) // コンパイルエラー
n = AliasType(n) // 可
}
// 可
func (d DefinedType) Validate() {
fmt.Println("some validation done")
}
// レシーバの箇所でコンパイルエラー
func (a AliasType) Validate() {
fmt.Println("some validation done")
}
一応 PlayGround のリンクも貼っておきます。
最後に
これを教えてくださった先輩エンジニアに感謝です。
Type alias の使い所が個人的にあまり掴めていないです。
参考
非常に参考になりました。
Discussion