A Tour of Go をやる! – その17 「Numeric Constants」 型無し野郎? 【Go言語/A Tour of Go】

2018年10月17日GoA Tour of Go,Goのお勉強,Go言語,,定数Go,A Tour of Go,Goのお勉強,Go言語,,定数

記事ヘッダー_Numeric Constants

「A Tour of Go をやる!」シリーズの第17回目。
暫く続いていた定数なお題ですが、今回も相変わらず定数の…しかも数値にフィーチャーした定数な内容のようです。

今回進めるページ「Numeric Constants」

今回進める「A Tour of Go」のページはこちら。

タイトルの「Numeric Constants」とは?

そのまま訳せば「数値の定数」。
という事で、前回も学習した定数の続き的な内容ぽいですが、今回はさらに数値に絞って学習するようです。

言語仕様の確認

それじゃ言語仕様。
今回のお題になっている「Numeric Constants」に絡んだ説明を引用してみます。

Constants may be typed or untyped. Literal constants, true, false, iota, and certain constant expressions containing only untyped constant operands are untyped.

定数は、型指定されている場合と型付けされていない場合があります。リテラル定数、true、false、iota、および型指定されていない定数オペランドのみを含む特定の定数式は型指定されていません。

A constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment or as an operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type.

定数は、定数の宣言または変換によって明示的に型を指定することも、変数の宣言または代入で使用する場合、または式のオペランドとして暗黙的に指定することもできます。定数値をそれぞれのタイプの値として表現できない場合はエラーになります。

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.

型なし定数にはデフォルトの型があります。これは、型付きの値が必要なコンテキストで定数が暗黙的に変換される型です。たとえば、明示的な型がないi:= 0などの短い変数宣言です。型なし定数のデフォルトの型は、ブール定数、ルーン定数、整数、浮動小数点、複素数、または文字列定数のいずれであるかに応じて、それぞれbool、rune、int、float64、complex128、またはstringです。

Implementation restriction: Although numeric constants have arbitrary precision in the language, a compiler may implement them using an internal representation with limited precision. That said, every implementation must:

実装の制限:数値定数は言語で任意の精度を持っていますが、コンパイラーは制限された精度の内部表現を使用してそれらを実装する場合があります。とはいえ、すべての実装は次のことを行う必要があります。

  • Represent integer constants with at least 256 bits.(256ビット以上の整数定数を表します。)
  • Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least ・256 bits and a signed binary exponent of at least 16 bits.(複素定数の一部を含む浮動小数点定数を表します。仮数は256ビット以上で、符号付き2進指数は16ビット以上です。)
  • Give an error if unable to represent an integer constant precisely.(整数定数を正確に表すことができない場合は、エラーを出します。)
  • Give an error if unable to represent a floating-point or complex constant due to overflow.(オーバーフローのために浮動小数点または複素定数を表すことができない場合は、エラーを出します。)
  • Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.(精度の制限のために浮動小数点または複素定数を表現できない場合は、最も近い表現可能な定数に丸めます。)

These requirements apply both to literal constants and to the result of evaluating constant expressions.

これらの要件は、リテラル定数と定数式の評価結果の両方に適用されます。(by Google Translated.)

https://golang.org/ref/spec#Constants

Constant expressions may contain only constant operands and are evaluated at compile time.

定数式には定数オペランドのみを含めることができ、コンパイル時に評価されます。

Untyped boolean, numeric, and string constants may be used as operands wherever it is legal to use an operand of boolean, numeric, or string type, respectively.

型なしのブール定数、数値定数、および文字列定数は、それぞれブール型、数値型、または文字列型のオペランドを使用することが合法である場合はいつでも、オペランドとして使用できます。

A constant comparison always yields an untyped boolean constant. If the left operand of a constant shift expression is an untyped constant, the result is an integer constant; otherwise it is a constant of the same type as the left operand, which must be of integer type.

定数を比較すると、常に型指定されていないブール定数が生成されます。定数シフト式の左側のオペランドが型指定されていない定数の場合、結果は整数定数になります。それ以外の場合は、左のオペランドと同じ型の定数であり、整数型である必要があります。

Any other operation on untyped constants results in an untyped constant of the same kind; that is, a boolean, integer, floating-point, complex, or string constant. If the untyped operands of a binary operation (other than a shift) are of different kinds, the result is of the operand’s kind that appears later in this list: integer, rune, floating-point, complex. For example, an untyped integer constant divided by an untyped complex constant yields an untyped complex constant.

型なし定数に対する他の操作は、同じ種類の型なし定数になります。つまり、ブール、整数、浮動小数点、複素数、または文字列定数です。二項演算(シフト以外)の型指定されていないオペランドの種類が異なる場合、結果はこのリストの後半に表示されるオペランドの種類(整数、ルーン、浮動小数点、複素数)になります。たとえば、型なし整数定数を型なし複素定数で割ると、型なし複素定数が生成されます。(by Google Translated.)

https://golang.org/ref/spec#Constant_expressions
const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
const b = 15 / 4           // b == 3     (untyped integer constant)
const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
const d = 1 << 3.0         // d == 8     (untyped integer constant)
const e = 1.0 << 3         // e == 8     (untyped integer constant)
const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
const h = "foo" > "bar"    // h == true  (untyped boolean constant)
const j = true             // j == true  (untyped boolean constant)
const k = 'w' + 1          // k == 'x'   (untyped rune constant)
const l = "hi"             // l == "hi"  (untyped string constant)
const m = string(k)        // m == "x"   (type string)
const Σ = 1 - 0.707i       //            (untyped complex constant)
const Δ = Σ + 2.0e-4       //            (untyped complex constant)
const Φ = iota*1i - 1/1i   //            (untyped complex constant)

つまり?

引用が予想以上に長くなりましたが…、型指定の無い定数についてまとめてみます。

  • 定数の型指定は自由
  • 型指定をしなかった場合は式によって型が判断される
  • さらにその型は Untyped const(型無し定数)となる
  • Untyped const でも基本となる型が合えば式で扱える
  • Untyped const は高精度(といっても上限はある。詳細は言語仕様参照)
// 型指定は自由
const one int = 1  // int
const one = 1      // Untyped integer constant

// 型は式で判断される+Untyped constとして扱われる
const one = 1      // Untyped integer constant
const one = "1"    // Untyped string constant
const one = 1.0    // Untyped floating-point constant

// Untyped const でも基本となる型が合えば式で扱える
const one = 1      // Untyped integer constant
var sum = one + 16 // sum = 17 (int)
const two = "2"    // Untyped string constant
var seventeen = two + 15  // こういうのは型が合わないのでエラー(mismatched types untyped string and untyped int)

// Untyped const は高精度だが上限もある
const hundred = 1<<100   // 百桁ビットは扱えるが…
const hundred = 1<<1000  // 千桁ビットは扱えない(constant shift overflow)

サンプルプログラムを見てみる。

一通り仕様を確認したのでサンプルプログラムを見てみます。
タイトルの「Numeric Constants」通り、数値の定数を扱ったサンプルプログラムのようです。

といった感じで、形無し定数を扱ったサンプルプログラムでした。

さいごに

とりあえず今回はここまで。
少しややこしい部分もありましたが、使い慣れれば「そういうもんだよな…」となるんでしょうねぇ。

それではまた次回~٩( 'ω’ )و

「Go言語のお勉強」インデックス

このシリーズについて

「A Tour of Go」を題材にした記事は現在書き直し中…。_(:3」∠)_
ほとんどサボりが原因で尻切れとなっていたシリーズですが、最近になってようやく続きを書きたくなり再開をしようと思ったんです。が、古い記事を見返すとデータ・フォーマットが古かったり内容が分かり難かったりに気づきまして、、、この際だからと最初の記事から書き直しをすることになりました…