😸

Go言語のdefined typeとは何か

3 min read

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ではありません。

  • STは、型定義により宣言された新しい型であるため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可能性」が最も広い、という関係にあります。

値xと型Tの関係性

それではこの集合の差分はどのような場合なのでしょうか?実は、この差の部分を記述するために、"defined type"の概念が使われています。詳しく知りたいかたは、Go言語仕様書を確認してみてください。

まとめ

Go言語の型は、defined typeである型と、そうでない型の2つに分けられます。

このうち、defined typeである型とは、次の2つのいずれかの型のことです:

  • 型定義によって宣言された新しい型
  • 事前宣言された型

逆に、defined typeではない型は、型リテラル(type literal)で表される型です。

脚注
  1. この記事は以前の発表資料を単独で読めるように記事化したものです。 ↩︎

  2. Type Parameters Proposalこの部分など、公式のドキュメントの中で、"defined type"という語をこれよりも狭く「型定義により宣言された新しい型」のみを指す意味に用いている場合があります。しかし、Go言語仕様書の上で正確な定義はあくまでこの記事にあげた2つの場合です。このように定義がわかりにくい故に混乱した用法も見られることが、この記事を執筆している動機でもあります。 ↩︎

GitHubで編集を提案

Discussion

ログインするとコメントできます