2016-01-05 10 views
5

リフレクションを使用すると、型名、記憶域サイズ、および指定された型の関数(uint64、ユーザー定義の構造体など)を取得できます。さらに、与えられた型のいくつかのフィールドを変更することもできます。 golangはどのように反射を実装していますか?私は、次の方法を推測:golangはリフレクションをどのように実装していますか?

  1. あらゆるタイプgolangで、ユーザー定義型を含む、それ自体は、型名の情報を持っている名前と関数名をフィールドに入力します。 Golangのリフレクションは、これらの情報を読み込んだり、関数を呼び出すだけです。

  2. いくつかのメカニズムを使用して、Golangはタイプ名、ストレージサイズなどを取得できます。タイプ自体にはこれらの情報はありません。

私はゴーリン反射コードをおおよそ読み取っています。私はgolangが第2の方法を使用したと推測しました。 リフレクションの具体的な実装方法は誰が記述できますか?または私にいくつかの文書をお勧めしますか?すべてのコードを読むのは難しいです。

+0

簡単に言えば、golangのリフレクションは、タイプ名、ストレージサイズ、フィールド、関数などのタイプの情報をどのように取得するのですか。さえ、反射は値を設定することができます。 –

答えて

4

これは単なる概観であり、100%正確ではないかもしれませんが、うまくいけば助けになると思います。ビルド時に

リンカーは実行可能ファイルに、アプリケーションによって使用されるすべてのタイプに関する情報を埋め込みます移動(https://github.com/golang/go/blob/master/src/runtime/symtab.go#L39

各インタフェース値は、からの変換時のデータタイプ記述子(https://github.com/golang/go/blob/master/src/runtime/type.go#L14

へのポインタを含みますインタフェース値Goコンパイラにコンパイル時に知られている型は、このインタフェース値の型記述子を具体的な型記述子にポイントします(コンパイル時には既知です)。

など。あなたはreflect.TypeOf(uint(87))を呼び出すとき:

  • インタフェース値はuint型記述子を参照するコンパイラによって作成された
  • このインタフェース値は、関数がで保存されている型記述子を使用しています
  • reflect.TypeOf引数としてreflect.TypeOf関数に渡され
  • uint型に関する整列(およびその他の)情報を取得する実行可能ファイル内のリンカ。
1

インターフェイスの説明については、The Laws of Reflectionで詳しく説明しています。

変数には具体的な値 とその値のタイプ記述子が割り当てられます。

基本的に、タイプはコードから静的にわかります。より柔軟なインターフェースタイプは、オリジナルの基本タイプを元のデータタイプに戻すために保持します。

+0

たとえば、 https://play.golang.org/p/KGTz2WscGY リフレクトメカニズムはuintタイプのアライメント情報をどのように取得しますか? –

関連する問題