0
我有一個創建從JSON,其定義如下的情況下,類對象轉換器功能:斯卡拉宏:方法重載
object JSONConverter {
import language.experimental.macros
def modelFromJson[T <: Model](json: JsValue):T = macro modelFromJson_impl[T]
}
我感興趣的創建從包含JSON字符串相同的對象也是。因此,我已改變上面的代碼如下重載原來的方法:
object JSONConverter {
import language.experimental.macros
// Using Play Framework library to parse a String to JSON
def modelFromJson[T <: Model](json: JsValue):T = macro modelFromJson_impl[T]
def modelFromJson[T <: Model](jsonString: String):T = {
val json: JsValue = Json.parse(jsonString)
modelFromJson[T](json)
}
}
但我收到此錯誤信息:
[error] ... not found: value T
[error] modelFromJson[T](json)
[error] ^
所以對於下面的配置
case class User(name: String, age: Int, posts:String, score: Double, lastLogin: DateTime) extends Model
// First case
JSONConverter.modelFromJson[User](someJsValueObject)
// Second case
JSONConverter.modelFromJson[User](someJsonString)
宏試圖返回以下表達式:
User.apply(json.$bslash("name").as[String], json.$bslash("age").as[Int], json.$bslash("posts").as[String], json.$bslash("score").as[Double], new DateTime(json.$bslash("lastLogin").as[Long]))
T.apply()
第一個是正確的,而第二個嘗試訪問T。
宏基本實現如下:
def modelFromJson_impl[T: c.WeakTypeTag](c: Context)(json: c.Expr[JsValue]): c.Expr[T] = {
import c.universe._
val tpe = weakTypeOf[T]
// Case class constructor
val generation = Select(Ident(newTermName(tpe.typeSymbol.name.decoded)), newTermName("apply"))
// Generate stuff like json.\("fieldName").as[String]
val fields = tpe.declarations collect {
...
}
val s = Apply(generation, fields.toList)
// Display results above for debugging
println(show(s))
c.Expr[T](s)
}
是否可以達到我想要的不進行其他宏?
非常感謝!
我不認爲這是可能的。不幸的是,在運行時,至少不能在Scala中抽象宏。 –
再次感謝尤金。 – Emre
以後有沒有計劃支持這個? – Emre