コンテンツにスキップ

Go/型と値の特性

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

型と値の特性

[編集]

型と値の特性(Properties of types and values)[1]

基礎となる型

[編集]

各型Tには、基礎となる型(underlying type)[2]があります[3]。 Tがあらかじめ宣言された論理型、数値型、文字列型、あるいは型リテラルのいずれかである場合、対応する基礎となる型はT自身です。 そうでない場合、Tの基礎となる型は、Tが宣言の中で参照する型の基礎となる型です。 型パラメーターの場合は、その型制約の基礎となる型で、それは常にインターフェースです。

コア型

[編集]

非インタフェース型Tはそれぞれコア型(core type)[4]を持ち、それはTの基礎となる型と同じです[5]。 インターフェースTがコア型を持つのは、以下の条件のいずれかが満たされる場合である。

  1. Tの型集合に含まれるすべての型の基礎となる単一の型Uが存在する。
  2. Tの型集合は,同一の要素型Eを持つチャネル型のみを含み、すべての方向性チャネルは同じ方向を持つ。

他のインターフェースはコア型を持たない。

インターフェースのコアタイプは、満たされる条件によって、次のいずれかになります。

  1. U型; または
  2. Tが双方向性チャンネルだけを含む場合はchan E型、存在する方向性チャンネルの方向によってはchan<- E型または<-chan E型

定義上、コア型は定義された型、型パラメータ、インタフェース型ではありません。

型同一性

[編集]

型同一性(Type identity)[6]

2つの型の間にある関係は、同じか異なるかのどちらかです。

定義された型は、常に他の型とは異なります。それ以外の場合、2つの型は、その基礎となる型リテラルが構造的に等価である場合、つまり、同じリテラル構造を持ち、対応するコンポーネントが同じ型を持つ場合、同一の型となります。詳しくは:

  • 2つの配列型は、要素の型が同じで、配列の長さが同じであれば同一です。
  • 2つのスライス型は、要素の型が同じであれば同一です。
  • 2 つの struct 型は、同じフィールドのシーケンスを持ち、対応するフィールドが同じ名前、同じ型、同じタグを持つ場合、同一の型となります。異なるパッケージからエクスポートされていないフィールド名は常に異なります。
  • 2つのポインター型は、基本型が同じであれば同一です。
  • 2つの関数型は、それらが同じ数のパラメータと結果値を持ち、対応するパラメータと結果の型が同じで、両方の関数が可変長であるか、どちらもそうでない場合、同一です。パラメータと結果の名前は一致する必要はありません。
  • 2つのインターフェース型は、同じ名前の同じメソッドのセットを持ち、同一の関数型を持つ場合、同一のものとなります。異なるパッケージからエクスポートされていないメソッド名は常に異なります。メソッドの順番は関係ありません。
  • 2つのマップ型は、同一のキー型とエレメント型を持つ場合、同一です。
  • 2つのチャンネル型は、要素型が同一で、方向が同じであれば同一です。

次に示す宣言があったとき

コード
type (
	A0 = []string
	A1 = A0
	A2 = struct{ a, b int }
	A3 = int
	A4 = func(A3, float64) *A0
	A5 = func(x int, _ float64) *[]string
)

type (
	B0 A0
	B1 []string
	B2 struct{ a, b int }
	B3 struct{ a, c int }
	B4 func(int, float64) *B0
	B5 func(x int, y float64) *A1
)

type	C0 = B0

これらの型は同一です。

コード
A0, A1, and []string
A2 and struct{ a, b int }
A3 and int
A4, func(int, float64) *[]string, and A5

B0 and C0
[]int and []int
struct{ a, b *T5 } and struct{ a, b *T5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5

func(int, float64) *B0 と func(x int, y float64) *[]string は、B0 が []string と異なるため、異なるものとなります。

代入可能性

[編集]

代入可能性(Assignability)[7]

xT 型の変数に代入可能である(「xTに代入可能である」)のは、次のいずれかの条件が当てはまる場合である。

  • x の型はTと同一である
  • x の型VTは基礎となる型が同一であり、V またはTの少なくとも一方は定義された型ではない
  • Tはインタフェース型であり、xT を実装している
  • x は双方向チャネル値であり、T はチャネル型であり、x の型VT は同一の要素型を持ち、V またはT の少なくとも一方は定義済みの型ではない
  • x は宣言済みの識別子nilであり、T はポインター、関数、スライス、マップ、チャネル、インターフェースのいずれかの型である
  • x は、T 型の値で表現可能な型付けされていない定数である

表現可能性

[編集]

表現可能性(Representability)[8]

定数 xは、以下の条件のいずれかに当てはまる場合、T 型の値で表現可能(representable)である。

  • x が、T によって決定された値のセットにある
  • T が浮動小数点型で、x はオーバーフローすることなくT の精度に丸められる
    丸めはIEEE 754 round-to-even規則を使用しますが、IEEE負のゼロはさらに符号なしのゼロに簡略化されます。なお、定数値はIEEE負のゼロ、NaN、無限大にはなりません。
  • T が複素数型で。x の成分real(x)とimag(x)は、T の成分型(float32またはfloat64)の値で表現できる


xT の値で表現できる例
x T xT の値で表現できる理由
'a' byte 97は byte の値の集合に含まれる
97 rune runeはint32の別名で、97は32ビット整数の値の集合に含まれる
"foo" string "foo" は string の値の集合に含まれる
1024 int16 1024 は 16-bit 整数の値の集合に集合に含まれる
42.0 byte 42 が 8-bit 整数の値の集合に含まれる
1e10 uint64 10000000000 is in the set of unsigned 64-bit integers
2.718281828459045 float32 2.718281828459045 は 2.7182817 に丸まられた上で float32 の値の集合に含まれる
-1e-1000 float64 -1e-1000 はIEEE -0.0 に丸められた上で、これはさらに簡略化され 0.0 となる
0i int 0 は整数の1つ
(42 + 0i) float32 42.0(虚数部がゼロ)は、float32の値のセットに含まれる


xT の値で表現できない例
x T xT の値で表現できない理由
0 bool 0は bool の値集合に含まれない
'a' string 'a' は rune で、string の値集合に含まれない
1024 byte 1024 は、unsigned 8-bit 整数の値集合に含まれない
-1 uint16 -1 は、unsigned 16-bit 整数の値集合に含まれない
1.1 int 1.1 は、整数(int)の値集合に含まれない
42i float32 (0 + 42i) が、float32 の値集合に含まれない
1e1000 float64 1e1000 オーバーフローし IEEE +Inf に丸められる

脚註

[編集]
  1. ^ “Properties of types and values ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022). https://golang.org/ref/spec#Properties_of_types_and_values. 
  2. ^ Underlying typeを基礎となる型と訳しました。
  3. ^ “Underlying types ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022). https://golang.org/ref/spec#Underlying_types. 
  4. ^ Core typeをコア型と訳しました。
  5. ^ “Core types ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022). https://golang.org/ref/spec#Core_types. 
  6. ^ “Type_identity¶”. The Go Programming Language Specification. The Go website. (March 10, 2022). https://golang.org/ref/spec#Type_identity. 
  7. ^ “Assignability¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Assignability. 
  8. ^ “Representability¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021). https://golang.org/ref/spec#Representability.