升降机类超过22个参数

时间:2013-09-18 16:45:12

标签: scala lift case-class

使用Lift,我正试图“提取”(得到一个案例类表示)我的JSON。

val json: JValue = getJson()
case class BigObj(name: String, age: Int, ...)
json.extract[BigObj]

当使用超过22个参数时,我得到一个JVM运行时异常,案例类不能超过22个参数。

我如何解决这个限制?

2 个答案:

答案 0 :(得分:2)

如前所述,您无法明确地使用案例类克服该限制,但是您可以使用不带案例类的抽取方法。请参阅此示例,我通过REPL运行以验证:

scala> import net.liftweb.json._
import net.liftweb.json._

scala> implicit val formats = net.liftweb.json.DefaultFormats
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@734784c4

scala> val json = parse(""" {
     |           "v1": "Test1",
     |           "v2": "Test2",
     |           "v3": "Test3",
     |           "v4": "Test4",
     |           "v5": "Test5",
     |           "v6": "Test6",
     |           "v7": "Test7",
     |           "v8": "Test8",
     |           "v9": "Test9",
     |           "v10": "Test10",
     |           "v11": "Test11",
     |           "v12": "Test12",
     |           "v13": "Test13",
     |           "v14": "Test14",
     |           "v15": "Test15",
     |           "v16": "Test16",
     |           "v17": "Test17",
     |           "v18": "Test18",
     |           "v19": "Test19",
     |           "v20": "Test20",
     |           "v21": "Test21",
     |           "v22": "Test22",
     |           "v23": "Test23"
     | } """)
json: net.liftweb.json.JValue = JObject(List(JField(v1,JString(Test1)), JField(v2,JString(Test2)), JField(v3,JString(Test3)), JField(v4,JString(Test4)), JField(v5,JString(Test5)), JField(v6,JString(Test6)), JField(v7,JString(Test7)), JField(v8,JString(Test8)), JField(v9,JString(Test9)), JField(v10,JString(Test10)), JField(v11,JString(Test11)), JField(v12,JString(Test12)), JField(v13,JString(Test13)), JField(v14,JString(Test14)), JField(v15,JString(Test15)), JField(v16,JString(Test16)), JField(v17,JString(Test17)), JField(v18,JString(Test18)), JField(v19,JString(Test19)), JField(v20,JString(Test20)), JField(v21,JString(Test21)), JField(v22,JString(Test22)), JField(v23,JString(Test23))))

scala> class MyLargeArgClass(val v1:String, val v2:String, val v3:String, val v4:String, val v5:String, val v6:String, val v7:String, val v8:String, val v9:String, val v10:String, val v11:String, val v12:String, val v13:String, val v14:String, val v15:String, val v16:String, val v17:String, val v18:String, val v19:String, val v20:String, val v21:String, val v22:String, val v23:String) {
     | 
     |   override def toString = "MyLargeArgClass(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)".format(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
     | 
     | }
defined class MyLargeArgClass

scala> json.extract[MyLargeArgClass]
res0: MyLargeArgClass = MyLargeArgClass(Test1, Test2, Test3, Test4, Test5, Test6, Test7, Test8, Test9, Test10, Test11, Test12, Test13, Test14, Test15, Test16, Test17, Test18, Test19, Test20, Test21, Test22, Test23)

然后从课堂回到JSON

scala> Extraction.decompose(res0)
res1: net.liftweb.json.JValue = JObject(List(JField(v1,JString(Test1)), JField(v2,JString(Test2)), JField(v3,JString(Test3)), JField(v4,JString(Test4)), JField(v5,JString(Test5)), JField(v6,JString(Test6)), JField(v7,JString(Test7)), JField(v8,JString(Test8)), JField(v9,JString(Test9)), JField(v10,JString(Test10)), JField(v11,JString(Test11)), JField(v12,JString(Test12)), JField(v13,JString(Test13)), JField(v14,JString(Test14)), JField(v15,JString(Test15)), JField(v16,JString(Test16)), JField(v17,JString(Test17)), JField(v18,JString(Test18)), JField(v19,JString(Test19)), JField(v20,JString(Test20)), JField(v21,JString(Test21)), JField(v22,JString(Test22)), JField(v23,JString(Test23))))

覆盖toString并非必要 - 我只需要查看正在添加的数据。但是,由于这不是case class,您将失去一些随附的自动方法。因此,如果您需要将其放在HTTP会话中,您可能希望实现Serializable。对于模式匹配,您需要unapply方法等...

您还应该能够使用formats指定自己的附加规则来解析和从JSON中提取数据。

答案 1 :(得分:1)

对于案例类,元组等,没有绕过22限制。这是Scala的限制。但是,如果您可以处理常规课程,那么您当然可以这样做。您将无法免费获得匹配,equalshashCode等。