Scala案例类使用Serializable扩展Product

时间:2016-04-10 04:30:02

标签: scala types traits case-class

我正在学习scala并尝试遵循Scala Cookbook:

trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal

现在当我跟随时:

val x = Array(Dog("Fido"),Cat("Felix"))

它显示结果为:

x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))

虽然我知道案例类与产品特征

混合在一起

我没有得到的是:Product with Serializable with Animal

根据我的理解,产品与模式匹配有关

我确实谷歌了,但没有得到任何东西。请帮助我详细了解这个概念。

谢谢

3 个答案:

答案 0 :(得分:37)

由于case class的工作方式,这是一种预期的行为。 case class自动extends两个特征,即ProductSerializable

Product特征被延长,因为case classalgebraic data type product type

Serializable特征被扩展,以便case class可被视为纯数据 - 即能够被序列化。

case class DogCat不同,您的特征Animal不会延伸ProductSerializable。因此你看到了类型签名。

当您声明Array(Dog(""), Cat(""))之类的内容时,scalac需要推断可以代表给定数组的所有元素的单top type

这就是为什么推断类型Product with Serializable with AnimalAnimalProduct没有延伸Serializable也不会case classAnimal隐式执行。

要解决此推理,您可以通过Animal明确指明类型,也可以Product扩展Serializabletrait Animal extends Product with Serializable case class Dog(name: String) extends Animal case class Cat(name: String) extends Animal Array(Dog(""), Cat("")) // Array[Animal] = Array(Dog(), Cat())

((e.Value["NewsOn"]))= DateTime.Now.ToString();

答案 1 :(得分:11)

Scala中的所有案例类都有一些属性:

  1. 他们将自动扩展Product特征,并为他们提供默认实施,因为它们可被视为a Cartesian Product of N records
  2. 他们将扩展Serializable,因为它们可以开箱即用(作为设计选择)。
  3. 他们将有一个由编译器提供的hashCodeequals的实现,它有助于模式匹配
  4. 他们将提供applyunapply方法,用于组合和分解类型。
  5. 案例类也是Scala表达Algebraic Data Type的方式,更具体地说是Product TypeTuples are also a product type,因此他们也扩展了Product特征。

    当您使用具有共同特征的两个案例类时,scala的编译器将使用它的类型推断算法来尝试找到Array的最佳匹配分辨率。

    如果您想避免看到此实现细节,可以让您的特征显式扩展这些特征:

    sealed trait Animal extends Product with Serializable
    

答案 2 :(得分:0)

所有案例类都会自动扩展ProductSerializable。看起来很难看?是。 基本上,Product可以被视为异构集合。所有产品类别即。 (Product1,Product2 ...)扩展Product,其中包含一些常用方法,例如productArityproductElement等。

与Case类一样,其他扩展Product的类型包括ListTuple

来自我的scala工作表,

  val product : Product = (10,"String",3)         //> product  : Product = (10,String,3)
  product.productArity                            //> res0: Int = 3
  product.productElement(0)                       //> res1: Any = 10
  product.productElement(1)                       //> res2: Any = String
  product.productElement(2)                       //> res3: Any = 3

case class ProductCase(age:Int,name:String,ISBN:Int)
  ProductCase(23,"som",5465473).productArity      //> res4: Int = 3

详情请见here