我的「動態實例case類」一個夢想 - 並提供根據每個字段類型的字段一些虛擬數據(我將創建以後的一些規則)斯卡拉2.10:動態實例case類
到目前爲止,我有一些代碼,以案例的類作品與String
; Long
或Int
......和我有點憋屈,如果它能夠處理嵌入case類
所以我可以實例case class RequiredAPIResponse (stringValue: String, longValue: Long, intVlaue: Int)
而不是外;其中,外是...
case class Inner (deep: String)
case class Outer (in : Inner)
的代碼是
def fill[T <: Object]()(implicit mf: ClassTag[T]) : T = {
val declaredConstructors = mf.runtimeClass.getDeclaredConstructors
if (declaredConstructors.length != 1)
Logger.error(/*T.toString + */" has " + declaredConstructors.length + " constructors --- only 1 currently supported.")
val constructor = declaredConstructors.headOption.get
val m = constructor.getParameterTypes.map(p => {
Logger.info("getName " + p.getName +" --- getCanonicalName " + p.getCanonicalName)
Logger.info(p.getCanonicalName)
p.getCanonicalName match {
case "java.lang.String" => /*"Name"->*/ val s : java.lang.String = "DEFAULT STRING"
s
case "long" => /*"Name"-> */ val l : java.lang.Long = new java.lang.Long(99)
l
case "int" => /*"Name"->*/ val i : java.lang.Integer = new java.lang.Integer(99)
i
case _ => /*"Name"->*/
So around here I am stuck!
//THIS IS MADE UP :) But I want to get the "Type" and recursively call fill
//fill[p # Type] <- not real scala code
//I can get it to work in a hard coded manner
//fill[Inner]
}
})
我覺得像Scala: How to invoke method with type parameter and manifest without knowing the type at compile time?最後的答案是答案的起點。 因此,而不是使用T- <:對象;填充應採取ClassTag或TypeTag? How can I transform a Map to a case class in Scala? - -
此代碼開始,其中提到(如電梯框架一樣)我確實有liftweb源代碼;但迄今爲止在解決所有祕密方面並未取得成功。
編輯---基於交互的點我有下面的代碼工作(一些小的更新,他的回答)
def fillInner(cls: Class[_]) : Object = {
val declaredConstructors = cls.getDeclaredConstructors
if (declaredConstructors.length != 1)
Logger.error(/*T.toString + */ " has " + declaredConstructors.length + " constructors --- only 1 currently supported.")
val constructor = declaredConstructors.headOption.get
val m = constructor.getParameterTypes.map(p => {
Logger.info("getName " + p.getName + " --- getCanonicalName " + p.getCanonicalName)
Logger.info(p.getCanonicalName)
p.getCanonicalName match {
case "java.lang.String" => /*"Name"->*/ val s: java.lang.String = "DEFAULT STRING"
s
case "long" => /*"Name"-> */ val l: java.lang.Long = new java.lang.Long(99)
l
case "int" => /*"Name"->*/ val i: java.lang.Integer = new java.lang.Integer(99)
i
case _ => fillInner(p)
}
})
constructor.newInstance(m: _*).asInstanceOf[Object]
}
def fill[T](implicit mf: ClassTag[T]) : T = fillInner(mf.runtimeClass).asInstanceOf[T]
感謝, 布倫特
大概ScalaTest或ScalaCheck有這樣的工作了自動生成測試用例。無形肯定是一個選項(從答案似乎凱馬也可能是):http://stackoverflow.com/questions/13402378/generically-rewriting-scala-case-classes –