Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何绕过Scala case类22个字段的限制?_Scala_Case Class - Fatal编程技术网

如何绕过Scala case类22个字段的限制?

如何绕过Scala case类22个字段的限制?,scala,case-class,Scala,Case Class,Scala案例类在构造函数中的字段限制为22个。我想超过这个限制,有没有一种方法可以通过继承或组合来实现它,它可以与case类一起工作?有趣的是,您的构造函数是加载的,但是您可以将相关的值打包到它们自己的case类中 所以虽然你可能有 case class MyClass(street: String, city: String, state: String, zip: Integer) 你可以这样做 case class MyClass(address: Address) 您还有其他选择:

Scala案例类在构造函数中的字段限制为22个。我想超过这个限制,有没有一种方法可以通过继承或组合来实现它,它可以与case类一起工作?

有趣的是,您的构造函数是加载的,但是您可以将相关的值打包到它们自己的case类中

所以虽然你可能有

case class MyClass(street: String, city: String, state: String, zip: Integer)
你可以这样做

case class MyClass(address: Address)
您还有其他选择:

  • 将项目分组为元组
  • 创建自己的
    Function23
    trait(或其他)
  • 使用

更新:正如其他人所指出的,在Scala 2.11发布后,这不再是一个问题——尽管我会犹豫是否使用“修复”一词。但是,如果您愿意,第三方Scala库中有时仍然会出现“Catch 22”。

这将在Scala 2.11中得到修复。

当您有那么多值时,这通常是一个迹象,表明你的设计无论如何都需要修改

形成间歇性案例类,然后聚合为更大的案例类。这也使得代码更易于理解、推理和维护。以及绕过这个问题,你有

例如,如果我想存储用户数据,我可能会这样做

case class User(name: Name, email: String)
case class Name(first: String, last: String)

事情这么少,这当然没有必要。但是,如果您有22件事情要塞进一个类中,那么无论如何,您都会想做这种间歇性的案例类工作。

构建一个普通类,其行为类似于案例类

我仍然使用scala 2.10.X,因为这是Spark支持的最新版本,在Spark SQL中,我大量使用case类

包含22个以上字段的
案例类的解决方法:

class Demo(val field1: String,
    val field2: Int,
    // .. and so on ..
    val field23: String)

extends Product 
//For Spark it has to be Serializable
with Serializable {
    def canEqual(that: Any) = that.isInstanceOf[Demo]

    def productArity = 23 // number of columns

    def productElement(idx: Int) = idx match {
        case 0 => field1
        case 1 => field2
        // .. and so on ..
        case 22 => field23
    }
}
最近(2016年10月,OP六年后),来自的博客文章“”探讨了这一限制:

回到2014年,Scala 2.11发布时,一个重要的限制被删除:

也就是说,案例类字段的数量仍然存在限制,请参见

这可能会让您认为Scala中没有22个限制,但事实并非如此限制存在于函数和元组中

Scala 2.11中引入的补丁()消除了上述常见场景的限制:构建案例类、字段访问(包括复制)和模式匹配()

它通过省略22个字段以上的案例类的
不应用
元组

换言之,限制仍然存在

在极限附近工作(Scala 2.11之后) 有两种常见的技巧可以绕过这个限制

  • 第一种方法是使用嵌套元组
    虽然一个元组不能包含超过22个元素,但每个元素本身可以是一个元组

  • 另一个常见的技巧是使用异构列表(HLists),其中没有22个限制

如果希望使用case类,最好使用无形状HList实现。我们已经创建了一个简单的解决方案。特别是在无形状的
HLists
和case类之间进行转换。看起来是这样的:

导入slick.driver.H2Driver.api_
进口不成形_
进口不光滑_
类LargeTable(tag:tag)扩展表[Large](tag,“Large”){
def a=列[Int](“a”)
def b=列[Int](“b”)
def c=列[Int](“c”)
/*等*/
def u=列[Int](“u”)
def v=列[Int](“v”)
def w=列[Int](“w”)
def*=(a::b::c::/*等*/::u::v::w::HNil)
.mappedWith(通用[大])
}
在不光滑的代码库中有一个


是的,你的权利。在某些情况下,我使用一个隐式的case类,它使用的字段比实际的类少。使用像json4s这样的对象映射器,它需要一个包含所有字段的case a类。这个答案是我第一个想到的,它或多或少是正确的。扩展产品为您提供了很好的迭代部分,但您没有得到copy方法。copy方法在case类中,但不是Product trait,因为它是由Scala编译器生成的(现在它可以为case类中的每个字段强类型)。您向Spark注册了什么序列化程序?我从twitter.chill.avro.AvroSerializer.SpecificRecordBinarySerializer开始,但在这种情况下,我的类必须实现SpecificRecordBase,这使我再次面临22个字段的限制。scala 2.11是救命稻草!
Case classes with > 22 parameters are now allowed.