Go/型と値の特性
型と値の特性
[編集]型と値の特性(Properties of types and values)[1]
基礎となる型
[編集]各型Tには、基礎となる型(underlying type)[2]があります[3]。 Tがあらかじめ宣言された論理型、数値型、文字列型、あるいは型リテラルのいずれかである場合、対応する基礎となる型はT自身です。 そうでない場合、Tの基礎となる型は、Tが宣言の中で参照する型の基礎となる型です。 型パラメーターの場合は、その型制約の基礎となる型で、それは常にインターフェースです。
コア型
[編集]非インタフェース型Tはそれぞれコア型(core type)[4]を持ち、それはTの基礎となる型と同じです[5]。 インターフェースTがコア型を持つのは、以下の条件のいずれかが満たされる場合である。
- Tの型集合に含まれるすべての型の基礎となる単一の型Uが存在する。
- Tの型集合は,同一の要素型Eを持つチャネル型のみを含み、すべての方向性チャネルは同じ方向を持つ。
他のインターフェースはコア型を持たない。
インターフェースのコアタイプは、満たされる条件によって、次のいずれかになります。
- U型; または
- 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]
値x がT 型の変数に代入可能である(「x はTに代入可能である」)のは、次のいずれかの条件が当てはまる場合である。
xの型はTと同一であるxの型VとTは基礎となる型が同一であり、VまたはTの少なくとも一方は定義された型ではないTはインタフェース型であり、xはTを実装しているxは双方向チャネル値であり、Tはチャネル型であり、xの型VとTは同一の要素型を持ち、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)の値で表現できる
xがTの値で表現できる例x T xがTの値で表現できる理由'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の値のセットに含まれる
xがTの値で表現できない例x T xがTの値で表現できない理由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 に丸められる
脚註
[編集]- ^ “Properties of types and values ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022).
- ^ Underlying typeを基礎となる型と訳しました。
- ^ “Underlying types ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022).
- ^ Core typeをコア型と訳しました。
- ^ “Core types ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022).
- ^ “Type_identity¶”. The Go Programming Language Specification. The Go website. (March 10, 2022).
- ^ “Assignability¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021).
- ^ “Representability¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021).