Go言語のdefined typeとは何か
defined type
Go言語仕様書を読み進めたり、Type Parameters Proposalを読む上で知っていると便利な概念の一つに"defined type"があります。
この概念はとても重要なのですが言語仕様書上での説明がわかりにくいため、わかりやすく正確に説明するのがこの記事の目的です。[1]
defined type の定義
Go言語の型は、defined typeである型と、そうでない型の2つに分けられます。
このうち、defined typeである型とは、次の2つのいずれかの型のことです:[2]
前者の例は例えば次のようなものです。
type MyInt int
// MyInt はdefined type
type MyMyInt MyInt
// MyMyInt もdefined type
後者の例はint
, string
, bool
, float64
などの型です。
defined typeではない型はtype literalで表される型である
それではdefined typeではない型とはなんでしょうか?それは、「型リテラル」で表される型です。型リテラルはさらに8種類に分けられます。いわゆる合成型を表す型がこれに当てはまります。
型リテラルの種類 | 具体例 |
---|---|
Slice型 | []int |
Array型 | [3]int |
Pointer型 | *int |
Map型 | map[Key]Value |
Interface型 | interface{ SomeMethod() } |
Struct型 | struct { ID int} |
Function型 | func(string) int |
Channel型 | chan int |
例題: どれがdefined typeでしょうか?
package main
type S []int
type T int
// S, T, []int, intという4つの型があるが、どれがdefined typeか?
定義(再掲)
defined typeである型とは、次の2つのいずれかの型のことです:
- 型定義によって宣言された新しい型
- 事前宣言された型
答え
S
T
int
の3つがdefined typeで、[]int
だけはdefined typeではありません。
-
S
とT
は、型定義により宣言された新しい型であるためdefined typeです。 -
int
は、事前宣言された型であるためdefined typeです。 -
[]int
は、このいずれにも当てはまらないためdefined typeではありません。- 逆からみて、
[]int
は型リテラルであるのでdefined typeではない、と考えても構いません。
- 逆からみて、
defined typeの理解が役立つ場面
defined typeの理解が役立つ場面としては、次のようなものがあります。
この最初の3つについて少し詳しくみてみましょう。
x
と型T
の関係性
値値x
と型T
の関係性として、次の3種類の関係があります。
- 値
x
の型と型T
とは同一である(型の同一性) - 値
x
は型T
の変数に代入可能である(代入可能性) - 値
x
は型T
にconvert可能である(convert可能性)
これらの成り立つ条件は包含関係にあり、「型の同一性」が最も狭く、「convert可能性」が最も広い、という関係にあります。
それではこの集合の差分はどのような場合なのでしょうか?実は、この差の部分を記述するために、"defined type"の概念が使われています。詳しく知りたいかたは、Go言語仕様書を確認してみてください。
まとめ
Go言語の型は、defined typeである型と、そうでない型の2つに分けられます。
このうち、defined typeである型とは、次の2つのいずれかの型のことです:
- 型定義によって宣言された新しい型
- 事前宣言された型
逆に、defined typeではない型は、型リテラル(type literal)で表される型です。
-
Type Parameters Proposalのこの部分など、公式のドキュメントの中で、"defined type"という語をこれよりも狭く「型定義により宣言された新しい型」のみを指す意味に用いている場合があります。しかし、Go言語仕様書の上で正確な定義はあくまでこの記事にあげた2つの場合です。このように定義がわかりにくい故に混乱した用法も見られることが、この記事を執筆している動機でもあります。 ↩︎
Discussion