入門Go言語仕様 / Go Specification Untyped Constants
by
DQNEO
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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
ご清聴 ありがとうございました