1 of 21

入門「Go言語仕様書輪読会」 2021/2/18 Thu

nobishii (@shino_nobishii)

2 of 21

はじめに

  • 仕様書を読み進めたり輪読会で議論するとき、馴染んでいると便利な概念のひとつがdefined typeです
  • 重要なわりに、仕様書の記述が少しわかりにくいので、まとめました
  • 本資料は公開し、仕様書の関連項目へのリンクも随所に貼ってあるので復習にもご利用ください

3 of 21

目次

  • 要約: defined typeの定義
  • defined typeを知るとわかること
  • Go言語の型3種類とdefined type
    • 事前宣言された型
    • 型リテラル
    • 型定義による型宣言
  • 具体例と例題
  • 展望 - 値xと型Tの関係性

4 of 21

要約: defined typeの定義

  • Go言語の型は、defined typeである型と、そうでない型の2つに分けられる
  • 次の2種類の型がdefined typeである:
    • 型定義によって宣言された新しい型
      • type MyInt intと書いたときのMyInt
    • 事前宣言された型
      • int, string, bool, uint32
  • defined typeではない型は、全て型リテラルで表される型である

5 of 21

defined typeを知るとわかること(深入りしません)

6 of 21

Go言語の型3種類とdefined type

事前宣言された型 (int, string…)

defined type

定義により宣言された型

defined type

型リテラルを用いて構成された合成型

defined typeではない

定義(再掲)

defined typeは、次の2種類の型である:

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

7 of 21

8 of 21

型リテラルとは: 次の8種類のリテラルであり、型を表す

[]int

SliceType

[10]int

ArrayType

*int

PointerType

map[Key]Value

MapType

interface {SomeMethod()}

interface {}

InterfaceType

struct {ID int}

StructType

func(string) int

FunctionType

chan int

ChannelType

9 of 21

型定義による型宣言とは:

type NewType SomeType

宣言された新しい型

(このNewTypeはdefined type)

既知の型

string

map[string]string

struct {

ID int

Name string

}

SomeKnownType(※定義済とする)

10 of 21

Go言語の型3種類とdefined type

事前宣言された型 (int, string…)

defined type

型定義により宣言された型

defined type

型リテラルを用いて構成された合成型

defined typeではない

定義(再掲)

defined typeは、次の2種類の型である:

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

11 of 21

Q. どれがdefined typeでしょうか?

package main

type S []int

type T int

定義(再掲)

defined typeは、次の2種類の型である:

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

12 of 21

A. どれがdefined typeでしょうか?

package main // S, T, intがdefined type

type S []int

type T int

定義(再掲)

defined typeは、次の2種類の型である:

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

13 of 21

展望: 値xと型Tの関係性とdefined type

深入りはしませんがちょっとだけdefined typeの役立つポイントをご紹介します

14 of 21

Overview: 値xと型Tの関係性:

型が同一代入可能 convert可能

15 of 21

Overview: 値xと型Tの関係性:

型が同一代入可能convert可能

16 of 21

まとめ: defined typeの定義

  • Go言語の型は、defined typeである型と、そうでない型の2つに分けられる
  • 次の2種類の型がdefined typeである:
    • 型定義によって宣言された新しい型
      • type MyInt intと書いたときのMyInt
    • 事前宣言された型
      • int, string, bool, uint32
  • defined typeではない型は、全て型リテラルで表される型である

17 of 21

Q & A

updated: 24th March 2021

18 of 21

Q. defined typeでないtypeはcomposite typeと呼べばいいんでしょうか?

A. ちょっと明確に答えられないところです。

composite typeという語は仕様書に現れるのですが明確に定義されていません。

[]string のような型リテラルがcomposite typeであることは確かなのですが、

type S []string のようにして定義したSがcomposite typeなのかどうかはっきりと言えないためです。

defined typeではない型に対する便利な名称は今のところ見当たりません。

19 of 21

Q. type alias で導入された名前は Defined Type じゃない、という理解でよいですか?

type aliasで導入された名前そのものは正確には「型に束縛された識別子」であって型ではありません。そういう意味ではYesです。

type aliasが束縛された型についていうと、defined typeである場合もあり、そうでない場合もあります。

20 of 21

Q. 代入可能集合の部分集合として型が同一とありますが、型が異なる場合で代入可能な例ってありますか?

はい、あります。

type S []string としたとき、Sと[]stringは異なる型ですが、

var s S

s = []string{}

のように代入可能です。

21 of 21

Q. すでに定義された型にtype definitionを使うメリットはなんですか?

1つは、それによって新たにメソッドを定義できるようになることです。

もう1つは、すでに定義されたdefined typeに対してtype definitionを使って新しいdefined typeを作ると、その2つの型はお互いに代入不可能になります:

var MyInt int // int型の値はMyInt型の変数に代入できない

これにより、underlying typeは等しいけれども意味が異なる値がある場合(郵便番号と名前、のような)、異なるdefined typeを割り当てることで代入のミスを事前に防ぐことができます。