2017-04-06 19 views
1

私はこのようなクラス定義しました:Scalaオブジェクト型を型パラメータに渡す方法は?

class Counta [T : TypeTag] { 
--cutted-- 
} 

をそして、私は、実行時に必要な正しいタイプで、このクラスをインスタンス化します。 私は、実行時にオブジェクトの正確な型を作成する機能を持っている:私はこのようなクラスをインスタンス化しようとすると、

def ConvertSparkTypesToScala(dataType: DataType) = { 
    dataType match { 
     case IntegerType => Int 
     case BooleanType => Boolean 
     case FloatType => Float 
     case DoubleType => Double 
     case LongType => Long 
     case ByteType => Byte 
     case ShortType => Short 
    } 
    } 

は今:

 val scalaType = ConvertSparkTypesToScala(dt) 
     println(scalaType) 
     val countA = new Counta[scalaType.type] 
     println(scalaType) 

私は例外と最初のprintlnのプリントを得る:

オブジェクトscala.Int

私は、例外が発生しました:

java.lang.UnsupportedOperationExceptionが:スキーマタイプに scalaType.typeが

をサポートしていませんので、基本的に、これはあなたのコードタイプを書くように同じように動作しません。 質問は、私が可能にしたいことですか?もしそうなら、これはどのように達成できますか?

+0

「ConvertSparkTypesToScala」では、タイプを返していないので、コンパニオンオブジェクトを返しています。実行時の情報をコンパイル時の情報に変換しようとしているようです。それはうまくいかないでしょう。 –

+0

あなたは何をしようとしているのか分かりませんが、反射を使用しているので震えます。あなたは考えましたか?https://github.com/typelevel/frameless? – flavian

答えて

1

おそらく、これらの行に沿って何かを試すことができます。しかし、私はあなたが単にしようとしていることは、おそらくXY problemなので、意味をなさないと思っています。

import scala.reflect.runtime.universe._ 

def ConvertSparkTypesToScala(dataType: DataType): TypeTag[_] = { 
    dataType match { 
    case IntegerType => typeTag[Int] 
    case BooleanType => typeTag[Boolean] 
    case FloatType => typeTag[Float] 
    case DoubleType => typeTag[Double] 
    case LongType => typeTag[Long] 
    case ByteType => typeTag[Byte] 
    case ShortType => typeTag[Short] 
    } 
} 

val dt: DataType = LongType 
val scalaTag = ConvertSparkTypesToScala(dt) 
println(scalaTag) 
val countA = new Counta()(scalaTag) 

countAは今CountaTを取るかTを生産する方法を持っている場合、コンパイラはTが本当に何であるかわからないため、これらの方法は、今ほとんど役に立たないことを意味し、実存タイプCounta[_]を持っています。

実行しようとしたのは、実行時にConvertSparkTypesToScalaメソッドで情報を計算し、その情報をコンパイル時に使用して、countAの型をコンパイラに伝えることでした。実行前には常にプログラムをコンパイルするので、実行時からコンパイル時に情報を流すことはできません。

あなたがcountAのタイプはdt

  1. に基づいて計算されるようにしたい場合は、(暗黙またはマクロや...で)コンパイル時に、それを計算する必要がありますし、
  2. 正確なタイプdtコンパイル時に知る必要があります。 dtのタイプが、DataTypeだけでなく、LongType.typeまたはIntegerType.typeでなければならないことを意味します。
関連する問題