Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Type Erasure と Reflection のはなし

yubessy
November 09, 2017

Type Erasure と Reflection のはなし

社内勉強会用資料です

yubessy

November 09, 2017
Tweet

More Decks by yubessy

Other Decks in Programming

Transcript

  1. " 静的型付け" とは? プログラムの実行前に変数や関数の型を決める プログラムの実行前 ≠ コンパイル時 例: mypy =

    型検査のみでコンパイルはしない とはいえ大抵はコンパイル時に型検査も行う
  2. 静的型付けのメリット めんどくさい? Map<String, String> listA = new HashMap<String, String>() むずかしい?

    ジェネリクス, 代数的デー タ型, ... 本来のメリット プログラムの実行前にエラー を検出 「 刀を抜く前に勝負をつける」!
  3. 実行時に型は必要? 実は必要ないケー スも多い 型検査が成功 ⇒ 実行時に型エラー が起こらない 型システムの健全性と呼ばれる (≠ 完全性)

    語りだすと長く(ry 型検査を通れば実行時に型情報は必要ない 「 当たらなければどうということはない」! 実際いくつかの言語ではType Erasure を行う
  4. 例: Java のジェネリクス List<String> list = new ArrayList<String>(); list.add("string"); String

    str = list.get(0); ↓ 型消去後のイメー ジ List list = new ArrayList(); list.add("string"); String str = (String) list.get(0);
  5. 例: Java のジェネリクス List<String> list = new ArrayList<String>(); list.add("string"); String

    str = list.get(0); 0 new java.util.ArrayList [15] 3 dup 4 invokespecial java.util.ArrayList() [17] 7 astore_1 [list] 8 aload_1 [list] 9 ldc <String "string"> [18] 11 invokeinterface java.util.List.add(java.lang.Object) : 16 pop 17 aload_1 [list] 18 iconst_0 19 invokeinterface java.util.List.get(int) : java.lang.Object 24 checkcast java.lang.String [30] 27 astore_2 [str]
  6. Re ection ( 自己言及) プログラムが自身のメタデー タを参照すること Runtime Re ection Compile

    Time Re ection Rei cation (Re ection による抽象構文木の操作) (ry 要するに Re ection があれば実行時に型情報を得られる
  7. 例: Scala のTypeTag import scala.reflect.runtime.universe._ // implicit ... によりコンパイラがTypeTag を生成

    // =「 あとでここの型情報を使うから覚えておいてね」 def paramInfo[T](x: T)(implicit tag: TypeTag[T]) = { val targs = tag.tpe match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") } scala> paramInfo(42) type of 42 has type arguments List() scala> paramInfo(List(1, 2)) type of List(1, 2) has type arguments List(Int)
  8. 例: Scala のTypeTag def paramInfo[T](x: T)(implicit tag: TypeTag[T]) = {

    val targs = tag.tpe match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") } ↓context bound を使うと略記できる def paramInfo[T: TypeTag](x: T) = { val targs = typeOf[T] match { case TypeRef(_, _, args) => args } println(s"type of $x has type arguments $targs") }
  9. おまけ: 型推論と型消去 実は型消去は型推論と対になる概念 Scala での型の一生 1. 人間は一部の型しか書かない 2. 型推論で頑張って型をつける 3.

    型検査で型エラー がないことを確認 4. 型消去でつけたばかりの型を消す 5. 一部の情報はリフレクションで記憶・ 参照