繁体   English   中英

Scala 案例类使用可序列化扩展产品

[英]Scala case class extending Product with Serializable

我正在学习 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

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

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

谢谢

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

Product trait 被扩展为case class是具有product type代数数据类型

Serializable trait 得到了扩展,因此case class可以被视为纯数据 - 即能够被序列化。

case class DogCat ,您的特征Animal不扩展ProductSerializable 因此,您看到的类型签名。

当您声明诸如Array(Dog(""), Cat("")) ,scalac 需要推断可以表示给定数组所有元素的单一顶部类型

这就是为什么推断的类型是Product with Serializable with Animal因为Animal没有扩展ProductSerializablecase class隐式地做了。

要解决此推断,您可以通过Animal使类型显式,或使Animal扩展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())

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

  1. 它们将自动扩展Product trait 并为它们提供默认实现,因为它们可以被视为N 条记录的笛卡尔积
  2. 它们将扩展Serializable因为它们是开箱即用的(作为设计选择)。
  3. 它们将具有编译器提供的hashCodeequals的实现,这有助于模式匹配
  4. 它们将提供applyunapply方法,用于类型的组合和分解。

Case 类也是 Scala 表达代数数据类型,更具体地说是产品类型的方式 元组也是一种产品类型,因此它们也扩展了Product特性。

当您使用具有共同特征的两个 case 类时,scala 的编译器将使用它的类型推断算法来尝试找到ArrayT类型的最小上限 (LUB)。 由于这两个 case 类都通过编译器扩展了ProductSerializable ,而trait没有,它会在搜索过程中将其应用到最终的计算类型。

如果你想避免看到这种情况,你可以让你的 trait 显式扩展这些 trait:

sealed trait Animal extends Product with Serializable

可以在此处找到有关此主题的更多信息

所有 case 类都会自动扩展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

详情请看这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM