Skip to content
shunsei.dev
Go back

Goでの型推論と%Tの内部動作の仕組みについて

Edit page

はじめに

最近、Goを書いていて「%T」で型情報の取得ができることが分かりました。ただ、その内部でどのような処理が行われているかについて、興味が沸いたので記事にします。

package main

import "fmt"

func main() {
	var x int = 1
	xx := float64(x)
	fmt.Printf("%T %v %f\n", xx, xx, xx)
}

上記のコードで%Tがどのように型を表示しているのか、型推論や型変換がどのように行われているのかを分解して解説します。

%Tは型推論ではない

結論から言うと、%Tは型推論ではありません。タイトル詐欺やん、そう思われた方は正解です。Go言語では型推論はコンパイル時に行われます。一方、%Tは実行時に指定した値の「型情報」を取得し、それをフォーマット文字列として出力する機能です。

コードの流れと内部動作

  1. var x int = 1 ここでは、明示的に型を指定して変数xを定義しています。
  1. xx := float64(x) この行では、int型の値xをfloat64型に変換しています。Goでは暗黙的な型変換は許されず、明示的に型を指定する必要があります。

内部で行われること

  1. 型変換の検証
    • xの型(int)がfloat64に明示的に変換可能であることを確認します
  2. 値の変換
    • 1(int型の値)が1.0(float64型の値)に変換されます。 この結果、xxの型はfloat64として推論されます。
  3. fmt.Printf(“%T %v %f\n”, xx, xx, xx) この行では、fmt.Printfが3つのフォーマット指定子を使ってxxの型と値を出力します。 フォーマット指定子の動作

型推論や型変換の仕組み

Goの型推論や型変換は次の手順で行われます。

  1. 型チェック(Type Checking)
    • 変数やリテラルの型を解析し、型が一致するかどうかを検証します。
  2. 型推論(Type Inference)
    • 明示的に型が指定されていなくても、右辺の値や関数の戻り値などから型を推論します。
  3. 型情報の保存
    • コンパイル時に変数の型情報を保存します。この型情報は実行時でも参照可能です。 %Tは、この保存された型情報をリフレクションを通じて実行時に取得し、フォーマットするだけです。 繰り返し登場しているリフレクションについて、軽く触れおきます。

リフレクションとは?

リフレクション(Reflection)とは、実行時にプログラム自身の構造や型、値を動的に調べたり操作したりする機能です。通常、プログラム内で型や構造はコンパイル時に決定しますが、リフレクションを使うと、実行時に型情報や値を取得して処理を行うことが可能になります。 Goでは、標準ライブラリのreflectパッケージを使うことでリフレクションを扱います。 実際にコード例を交えながら見ていきましょう。以下のコードでは、リフレクションを用いて変数の型を調べています。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var x float64 = 3.14
	// reflect.TypeOf で型情報を取得
    // 実行結果 Type: float64
	fmt.Println("Type:", reflect.TypeOf(x))
	// reflect.ValueOf で値情報を取得
    // 実行結果 Value: 3.14
	fmt.Println("Value:", reflect.ValueOf(x))
}

%Tとリフレクションの関係

Goのfmt.Printf(“%T”, …)は内部的にリフレクションを使って型情報を取得しています。ただし、プログラマーがreflectパッケージを直接操作するわけではなく、%Tを使うだけでリフレクションの恩恵を簡単に受けられる仕組みになっています。 つまり、先程のコードは%Tを1つの処理として書き換えたものと思ってもらえれば十分です。 そのため、リフレクションを知らなくても%Tを使えますが、リフレクションの仕組みを知っておくと、Goの動的な型処理について理解が深まります。

リフレクションを使うべき場面と注意点

リフレクションは強力な機能ですが、次のような場面で使うことが推奨されます。

型推論と%Tの違い

機能役割
型推論コンパイル時に変数の型を自動的に決定する
%T実行時に変数の型情報を取得して文字列として出力。
:::message
%Tは型推論ではなく、既に決定された型情報を取得して表示するための機能です。
:::

まとめ

Go言語では型推論と型変換が厳密に設計されており、開発者にとって予測可能で安全なコードを書く助けとなっています。一方で、%Tを使って型情報を表示することで、型についての理解を深めたりデバッグに役立てたりすることができます。 この記事がGoの型システムへの理解を深める手助けになれば幸いです。


Edit page
Share this post on:

Previous Post
GoでE2EE(エンドツーエンド暗号化)を実装してみた
Next Post
ショート形式 := が関数内でしか使えない理由とvarの重要性