首页 文章

Scala案例类使用Serializable扩展Product

提问于
浏览
16

我正在学习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 trait混在一起

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

As per my understanding Product has something to do with Pattern matching

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

谢谢

3 回答

  • 11

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

    Product 特征被扩展,因为 case class 是一个带有product typealgebraic data type .

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

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

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

    这就是为什么推断类型是 Product with Serializable with Animal ,因为 Animal 没有延伸 Product 也没有 Serializable ,而 case class 隐含了 .

    要解决此推理,您可以通过 Animal 使类型显式化,也可以使 Animal extend ProductSerializable .

    trait 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())
    
  • 0

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

    • 他们将自动扩展 Product 特征,并为他们提供默认实现,因为它们可以被视为a Cartesian Product of N records .

    • 他们将扩展 Serializable ,因为它们可以开箱即用(作为设计选择) .

    • 它们将具有编译器提供的 hashCodeequals 的实现,这有助于模式匹配

    • 他们将提供 applyunapply 方法,用于组合和分解类型 .

    案例类也是Scala表达Algebraic Data Type的方式,更具体地说是Product Type . Tuples are also a product type,因此他们也扩展了 Product 特征 .

    当您使用具有共同特征的两个案例类时,scala 's compiler will use it' s类型推断算法尝试为 Array 找到最佳匹配分辨率 .

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

    sealed trait Animal extends Product with Serializable
    
  • 35

    所有案例类都自动扩展 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 .

相关问题