2017-04-06 111 views
1

我定義的類是這樣的:Scala如何將Object類型傳遞給類型參數?

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打印:

object scala.Int

then我得到異常:

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現在有生存型Counta[_],這意味着如果Counta有需要T或產生T方法,這些方法是幾乎無用了,因爲編譯器不知道什麼T真的是。

您試圖做的是在運行時在ConvertSparkTypesToScala方法中計算信息,然後在編譯時使用該信息告知編譯器countA將是什麼類型。在程序運行之前,您將始終編譯程序,因此信息不可能從運行時流入編譯時間。

如果你想的countA類型基於dt

  1. 你需要計算它在編譯時(與implicits或宏或...),並
  2. 精確型dt計算需要在編譯時知道;這意味着dt的類型必須是LongType.typeIntegerType.type,而不僅僅是DataType
相關問題