2017-04-10 6 views
1

ケースパラメータBlaをタイプパラメータAとし、実行時にAのタイプを知っています(infoフィールドに格納します)。ケースクラスのタグ

私の試みは以下の例に示されています。問題は、この例はコンパイルされないということです。私はval info=Run.paramInfo(this)コメント際

case class Bla[A](){ 
    val info=Run.paramInfo(this) // this does not compile 
} 
import scala.reflect.runtime.universe._ 

object Run extends App{ 
    val x=Bla[Int] 
    def paramInfo[T](x:T)(implicit tag: TypeTag[T]): String = { 
    val targs = tag.tpe match { case TypeRef(_, _, args) => args } 
    val tinfo=s"type of $x has type arguments $targs" 
    println(tinfo) 
    tinfo 
    } 
    paramInfo(x) 
} 

しかしその後、プログラムが正常に動作して印刷:のBlaの

タイプは、()

(int)を引数リストを入力しているようにする方法はありますこの例はコンパイルしますか? (または他の方法で同じ目標を達成します。つまり、ケースクラスは型パラメータの型を自己認識していますか?)

答えて

2

暗黙の型タグパラメータをケースクラスコンストラクタに渡してください情報が)それを必要とするparaInfoを呼び出す前に失われたタイプ:

の省略形です
case class Bla[A : TypeTag]() { ... } 

:このためにリフレクションベースのAPIを使用して、ほとんどのポイントがあります

case class Bla[A](implicit tag: TypeTag[A]) { ... } 
+0

ありがとうございました。 – jhegedus

3

、型崩れがコンピを公開する型クラスを持っています暗黙的なマクロを使用して、実行時に情報を取得します。

import shapeless.Typeable 


class Test[T : Typeable] { 
    def info: String = implicitly[Typeable[T]].describe 
} 

それは、それを使用しているものは何でもとは異なるコンパイル単位での暗黙のマクロをコンパイルすることの追加不便で、ここにあなた自身のことをロールバックすることも比較的簡単です。

+0

ありがとう、 'TypeTag'を使うとき、コンパイル時に' info'の値が決まっていませんか? – jhegedus

+1

@jhegedusいいえ、TypeTagはリフレクションAPIのものですが、これはjavaの 'Class [_]'のより進化したバージョンです。 – flavian

+0

TypeTagの値は、コンパイル時に決定されるようです。「scala.reflect.Manifestと同様に、TypeTagsは、コンパイル時に使用可能なすべての型情報を実行するオブジェクトとして考えることができます。 ]は、コンパイル時の型Tの実行時の型表現をカプセル化します。ただし、型タグは、マニフェストの2.10より前の概念のより豊かなものとみなされるべきであり、さらにScalaのリフレクションに完全に統合されています。 http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html – jhegedus

関連する問題