入門Go言語仕様 / Go Specification Untyped Constants
by
DQNEO
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
入門Go言語仕様輪読会 Untyped Constants @DQNEO 2021-04-15
Slide 2
Slide 2 text
自己紹介 ● @DQNEO (ドキュネオ) ● Goコンパイラ babygo の作者 ○ https://github.com/DQNEO/babygo ● 公式Goコンパイラ、言語仕様書コントリビュート歴有り
Slide 3
Slide 3 text
問題: 次の値の型は何でしょうか? 123 "hello" true
Slide 4
Slide 4 text
答え: なし 123 "hello" true ← 型なし ← 型なし ← 型なし
Slide 5
Slide 5 text
問題: 次の2文は何が違うでしょうか? const x = 123 var x = 123 注: const / var 違いの他に
Slide 6
Slide 6 text
答え: 型が違う const x = 123 var x = 123 var x int = 123 両辺とも型なし 両辺とも int =
Slide 7
Slide 7 text
型なし?
Slide 8
Slide 8 text
Go言語の定数は ● 型あり ● 型なし のどちらか
Slide 9
Slide 9 text
これらは全部型なし定数 ● 123 ● 1.1 ● "hello" ● ‘a’ ● true ● 1.0+3.0i
Slide 10
Slide 10 text
型なし定数を作ることも可能 const THREE = 3 const HELLO = "hello" 左辺で型を省き、右辺で型なし定数を使う
Slide 11
Slide 11 text
型なし定数のおもしろ性質(1) _人人人人人人_ > 型がない <  ̄Y^Y^Y^Y^Y^Y^ ̄
Slide 12
Slide 12 text
型がないのでユーザ定義型に代入可能 type MyBool bool var b MyBool = true もし true が bool 型だったら、代入できないはず (代入可能性の解説はこちら ) https://play.golang.org/p/63VHrn7XQVY
Slide 13
Slide 13 text
const HELLO = "hello" type MyString string var s MyString = HELLO もし HELLO が string型だったら、代入できない 型がないのでユーザ定義型に代入可能 (代入可能性の解説はこちら )
Slide 14
Slide 14 text
型がないのでいろんな型に代入可能 var y float32 = 97 var x int64 = 'a' var z byte = 97.0 (※ ただし “representable” な場合に限る) どれも 右辺は 「左辺の型の97」扱い
Slide 15
Slide 15 text
型なし定数のおもしろ性質(2) 「型を隠し持っている」
Slide 16
Slide 16 text
型なし定数にも種類がある リテラル 種類 1 integer constant 1.0 floating-point constant 'a' rune constant "hello" string constant true boolean constant
Slide 17
Slide 17 text
種類に応じて default type がある リテラル 種類 default type 1 integer constant int 1.0 floating-point constant float64 'a' rune constant rune(=int32) "hello" string constant string true boolean constant bool
Slide 18
Slide 18 text
var x = 1.0 型が必要です。 あなたの型を教えてください float64 です 聞かれたときだけ答える default type とは、 「型を要求されたとき」に使われる型
Slide 19
Slide 19 text
型を要求される文脈の例 ● var x = 123 ● y := 1.0 ● var ifc interface{} = 1.0 ● fmt.Printf("%v", 1.0)
Slide 20
Slide 20 text
● var x uint8 = 1.0 私は uint8型です。 私に従ってください わかりました default typeは、必ずしも使われるわけでは ない uint8として振る舞う default typeは使われない
Slide 21
Slide 21 text
型なし定数のおもしろ性質(3) 「すごい数もOK」
Slide 22
Slide 22 text
超巨大数を定義できる const HUGE = 92233720368547758070 ↑ int64の最大値より大きい
Slide 23
Slide 23 text
定義できるが表示できない const HUGE = 92233720368547758070 fmt.Println(HUGE) _人人人人人人_ > コンパイルエラー <  ̄Y^Y^Y^Y^Y^Y^ ̄ constant 92233720368547758070 overflows int64
Slide 24
Slide 24 text
int型変数に代入できない const HUGE = 92233720368547758070 var x = HUGE constant 92233720368547758070 overflows int64 _人人人人人人_ > コンパイルエラー <  ̄Y^Y^Y^Y^Y^Y^ ̄
Slide 25
Slide 25 text
Go言語氏 「default type があるとは言ったが、 default type に収まるとは言ってない」
Slide 26
Slide 26 text
float型変数には代入できる const HUGE = 92233720368547758070 var x float64 = HUGE fmt.Printf("%v\n", x) => 9.223372036854776e+19 精度は落ちる (当然)
Slide 27
Slide 27 text
巨大数同士の定数計算ができる const HUGE = 92233720368547758070 const X_HUGE = 922337203685477580700 var x uint8 = X_HUGE / HUGE 計算結果がuint8 に収まるのでOK => 10
Slide 28
Slide 28 text
超細かい小数を定義できる const ROOT2 = 1.41421356237309504880168872420969807856 967187537694807317667974 float64 の精度を超えている
Slide 29
Slide 29 text
二乗すると 2 になる const ROOT2 = 1.41421356237309504880168872420969807856 967187537694807317667974 fmt.Println(ROOT2 * ROOT2) // => 2 _人人人人人人_ > 精度高すぎ <  ̄Y^Y^Y^Y^Y^Y^ ̄
Slide 30
Slide 30 text
変数を経由すると精度が落ちる const ROOT2 = 1.41421356237309504880168872420969807856 967187537694807317667974 f := ROOT2 // ここで float64に詰め替えられる fmt.Println(f * f) // => 2.0000000000000004 https://play.golang.org/p/JMtw6IZjDtP
Slide 31
Slide 31 text
Goの言語思想 “they are just regular numbers” 型なし定数の数値は「ただの数」である const HUGE = 92233720368547758070 const ROOT2 = 1.4142135623730950488016887242096980785696718753769 4807317667974 https://blog.golang.org/constants
Slide 32
Slide 32 text
Goの言語思想 “they live in a kind of ideal space of values” 型なし定数は、型の制約のない自由な理想空間 で生きている
Slide 33
Slide 33 text
Goの言語思想 1 1.000 1e3-99.0*10-9 '\x01' ‘a’ (= ‘0x97 ’ 97) '\u0001' 'b' - 'a' 1.0+3i-3.0i これらはどれも 型なし定数 1 と同等に扱える
Slide 34
Slide 34 text
おまけ この辺は例外的な仕様 ● string(97) // => "a" ● string(97.0) // コンパイルエラー
Slide 35
Slide 35 text
ご清聴 ありがとうございました