入門Go言語仕様輪読会 2/18メモ

入門Go言語仕様輪読会 2/18

概要

gospecreading.connpass.com

Defined type:Nobisii

defined type 仕様書を読んだり、輪読会で議論するときに便利な概念

Goの型: defined type とそうでないものに分けられる(そうでないものに対する名称はないらしい)

defined typeのもの 1. 型定義によって宣言されたもの 2. 事前宣言されたもの(bool int など)

そうでないもの=全て型リテラルで表されるもの、合成型

defined type を知ると分かること

  • 型の同一性
  • 代入可能性
  • convert可能性など

リテラル

リテラル:8種類

    SliceType
    ArrayType
    PointerType
    MapType
    InterfaceType
    StructType
    FunctionType
    ChannelType

型定義による型宣言

type NewType SomeType
package main
type S []int // defined typeでない
type T int // defined type
// int はdefined type

値xと型Tの関係性 Convert可能 代入可能 型が同一 この説明にdefined typeを使う

composite type // defined typeでない?<=微妙に議論がわかれる

type aliasは導入の型次第

type I1 int // defined type
type I2 = int // defined type
type I3 = []int // defined typeでない
// type alias はメソッドを定義できる、型を置き換えして把握

型宣言のメリット

type A []int

func (A) Sum() int { // メソッドをつけられる

}
// 代入をできないようにする:意味分けをする、エラーコードの分類など
type A int

type B A

func main() {
    var a A
    var b B
    a = 1
    b = 2
    a = b

}

Underlying types DQNEO

underlying

  • 何かの下に横たわる
  • 今回は背後霊ととらえる

なぜ重要なのか

  • 代入可能性の条件に使われる
  • Genericsで重要な役割
type MyInt int //MyIntのunderlying type はint

全ての型にはunderlying typeがある

int のunderlying type はint

3つのルール

  • 1 事前宣言されたbool, string, numericのunderlying type は自分自身
  • 2 複合型、型リテラルのunderlying typeは自分自身 struct{}
type User struct{
    a int
    name string
}

Methodの継承

  • interface型: 継承される
  • underlying typeで判断

なぜヒエラルキーがない? → Goの誕生時に、大きいプログラムでは、木構造で型の継承関係を整理するのに時間がかかっている。型システムをクリアに保つ。型の階層がなくてもオブジェクト指向はできる

型を直接共有する

type (
    B1 string
    B2 B1
    B3 []B1// []B1, []B1, []B1
    B4 B3
)

stringから[]byte,underlying typeが違うがconversionできる conversionのルールには使われる underlying typeが同じ場合は変換できる(十分条件)

sliece と underlying array サイズの大きさが違う、違う概念

type Slice struct {
    ptr *byte // <- underlying array
    len int64
    cap int64
}

error型のルール

type error interface {
    Error() string
}

代入可能性

type MyInt1 int
type MyInt2 int
func main() {
    var i1 MyInt1
    var i2 MyInt2
    i2 = 99
    i1 = i2 // コンパイルエラー
}

循環参照はそのままコンパイルエラーにできるのでそこではじく