Scala案例类在构造函数中限制为22个字段。我想超过这个限制,有没有办法用继承或组合使用案例类?
答案 0 :(得分:37)
最近(2016年10月,OP后六年),博客文章" Scala and 22"来自Richard Dallaway探讨了这个限制:
早在2014年,当Scala 2.11发布时,一个重要的限制就被删除了:
Case classes with > 22 parameters are now allowed.
尽管如此,案例类字段的数量仍然存在限制,请参阅https://stackoverflow.com/a/55498135/1586965
这可能会让您认为Scala中没有 22限制,但事实并非如此。 限制依赖于函数和元组。
Scala 2.11中引入的修复(PR 2305)消除了上述常见场景的限制:构建案例类,字段访问(包括复制)和模式匹配(baring edge cases)。
通过省略22个字段以上的案例类
unapply
和tupled
来实现此目的 换句话说,Function22
和Tuple22
的限制仍然存在。解决限制(发布Scala 2.11之后)
有两种常见的技巧可以绕过这个限制。
第一种是使用嵌套元组 虽然元组不能包含超过22个元素,但每个元素本身都可以是一个元组
另一个常见的技巧是使用异构列表(HLists),其中没有22个限制。
如果您想使用案例类,最好使用无形HList实现。我们创建了Slickless library以使其更容易。特别是the recent
mappedWith
method在无形HLists
和案例类之间进行转换。它看起来像这样:
import slick.driver.H2Driver.api._
import shapeless._
import slickless._
class LargeTable(tag: Tag) extends Table[Large](tag, "large") {
def a = column[Int]("a")
def b = column[Int]("b")
def c = column[Int]("c")
/* etc */
def u = column[Int]("u")
def v = column[Int]("v")
def w = column[Int]("w")
def * = (a :: b :: c :: /* etc */ :: u :: v :: w :: HNil)
.mappedWith(Generic[Large])
}
Slickless代码库中有一个full example with 26 columns。
答案 1 :(得分:30)
此issue将在Scala 2.11中修复。
答案 2 :(得分:19)
有趣的是你的构造函数是加载的,但你可以将相关的值打包到自己的case类中。
所以你可能有
case class MyClass(street: String, city: String, state: String, zip: Integer)
你可以这样做
case class MyClass(address: Address)
您还有其他选择:
Function23
特征(或其他)更新:正如其他人所说,在Scala 2.11发布后,这不再是一个问题 - 尽管我会毫不犹豫地使用术语“修复”。但是,如果您愿意,“Catch 22”有时仍会显示在第三方Scala库中。
答案 3 :(得分:-3)
当你拥有那么多价值观时,通常表明你的设计需要重新设计。
形成间歇性案例类,然后聚合成较大的案例类。这也使代码更容易理解,推理和维护。除了绕过这个问题,你还有。
例如,如果我想存储用户数据,我可能会这样做....
case class User(name: Name, email: String)
case class Name(first: String, last: String)
由于事情很少,这当然不是必要的。但是如果你有22件东西要塞进一个班级,那么无论如何你都会想做这种间歇性的案例课。