2017-11-25 7 views
0

ManifestTypeTagにいくつか質問があります。私は、JVMがジェネリックスについて知らず、タイプを消去することを理解しています。だから私はManifestを使用して、実行する種類の情報を転送することができ、このマニフェストはなぜ非難されましたか?いつClassTagを使用する必要がありますか?TypeTagを使用する必要があるのはいつですか

def factoryForAll[T] = new T // will not compile. Runtime doesn't know what T is 

Scalaのコンパイラを行うことはできません(現在は非推奨)。 Manifestには、タイプに関する情報を含むerasureのようなメソッドがあります。だから私は、ジェネリック型のオブジェクトを作成するには、次のことができないT

def factoryForall[T](implicit ev:Manifest[T]) = ev.erasure.newInstance 

scala> factoryForAll[String] 
res1:Any="" 

scala> class C 
defined class C 

scala> factoryForAll[C] 
res5: Any = [email protected] 

質問1 - 興味深い、それがintのために働く(またはフロート)しないのですか?どうして?

scala> factoryForAll[Int] 
java.lang.InstantiationException: int 

質問2 - なぜ廃止予定マニフェストましたか? Scalaの2.12はまだManifestクラス(https://www.scala-lang.org/api/current/scala/reflect/Manifest.html)を持っている - 私は新しいバージョン、TypeTagは、より豊かな情報を持っているが、私はマニフェストにおける欠点

質問3何であったかを理解していないことを理解しています。 Manifestが悪い場合、Scalaにはまだそれがありますか?ドキュメントではManifestを使用してArraysのGeneric型を作成することを指していますが、配列はClassTagでも実装できます。では、なぜScalaにはまだManifestがあるのですか? TypeTagに来る

scala> def makeArray[T](len:Int)(implicit ev:ClassTag[T]) = new Array[T](len) 
makeArray: [T](len: Int)(implicit ev: scala.reflect.ClassTag[T])Array[T] 

scala> makeArray[String](4) 
res39: Array[String] = Array(null, null, null, null) 

scala> makeArray[Int](4) 
res40: Array[Int] = Array(0, 0, 0, 0) 

scala> val al = makeArray[List[Int]](2) 
al: Array[List[Int]] = Array(null, null) 

scala> al(0) = List(1) 

scala> al(1) = List(2,3) 

、3種類があります。 Scalaのドキュメント(http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html)と中(https://medium.com/@sinisalouc/overcoming-type-erasure-in-scala-8f2422070d20)のチュートリアルを参照すると、私はTypeTagClassTagのユースケースが異なることを理解しています。 ClassTagでは、第1レベルの消去を超えて型を区別することはできません。

//method to extract a type from a collection 
def extractType[T](col:Iterable[Any])(implicit ev:ClassTag[T]) = { 
val it =col.iterator 
while (it.hasNext) { 
val el = it.next 
el match { 
case x:T => println("got T") 
case _ => println("not T") 
}}} 

extractType: [T](col: Iterable[Any])(implicit ev: scala.reflect.ClassTag[T])Unit 

scala> extractType[Int](List(1,2,3,"hello")) 
got T 
got T 
got T 
not T 

scala> extractType[List[Int]](List(List(1),List(2),List(3),List("hello"))) 
got T 
got T 
got T 
got T //this should be not T 

Question4:ClassTagは消去の第一レベルを区別することができない場合は、私がList[Set[Int]]Stringを追加しようとすると、なぜ私は次のエラーを取得しますか。 Intは消去されていませんか?

scala> def makeArray[T](len:Int)(implicit ev:ClassTag[T]) = new Array[T](len) 
makeArray: [T](len: Int)(implicit ev: scala.reflect.ClassTag[T])Array[T] 

scala> val al = makeArray[List[Set[Int]]](2) 
al: Array[List[Set[Int]]] = Array(null, null) 

scala> al(0) = List(Set(2)) 

scala> al(1) = List(Set("2")) 
<console>:28: error: type mismatch; 
found : String("2") 
required: Int 
     al(0) = List(Set("2")) 
         ^

Question5 - なぜ以前の例extractType[List[Int]](List(List(1),List(2),List(3),List("hello")))では、ScalaはIntからStringを区別することができませんでしたが、それはal(0) = List(Set(2))al(1) = List(Set("2"))

質問6区別 - どのように私はそのextractType機能などを変更できますか埋め込みタイプをチェックすることができます。私はTypeTagを使用しなければならないことを知っていますが、コレクション内の要素のタイプをチェックする方法はわかりません。

def extractType[T](col:Iterable[Any])(implicit ev:TypeTag[T]) = { 
    println("class is "+ev.mirror.runtimeClass) //I suppose in TypeTag, runtime is here 
    val it =col.iterator 
    while (it.hasNext) { 
    val el = it.next 
    el match { 
     case x:T => println("got T") //this doesn't compile. What should I check for? 
     case _ => println("not T") 
    }}} 

答えて

1

質問1:Intと(彼らはClassオブジェクトを対応しているが)FloatはJVM内のクラスで表現されていない、パラメータなしのコンストラクタを持っているだけでものをみましょう。名前にforAllがあるにもかかわらず、これは非常に限定されたタイプのセットで機能します。

質問2:Manifestは、ClassTagTypeTagが別々の懸念を混ぜています。

質問3:このエラーは、静的な型al: Array[List[Set[Int]]]から来ている:あなたはManifestのソースを見れば、それは

// TODO undeprecated until Scala reflection becomes non-experimental 
// @deprecated("use scala.reflect.ClassTag (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") 

質問4/5を言います。 ClassTagまたはTypeTagによって提供されるランタイム情報は含まれません。

質問6:標準ライブラリのみを使用することはできません。しかし、Shapelessを参照してください。

関連する問題