我正在学习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 回答
由于
case class
的工作原理,这是一种预期的行为 .case class
自动extends
两个特征,即Product
和Serializable
.Product
特征被扩展,因为case class
是一个带有product type的algebraic data type .Serializable
特性被扩展,以便case class
可以被视为纯数据 - 即能够被序列化 .与
case class
Dog
和Cat
不同,您的特征Animal
不会延伸Product
或Serializable
. 因此,您看到的类型签名 .当您声明
Array(Dog(""), Cat(""))
之类的内容时,scalac需要推断单个top type,它可以表示给定数组的所有元素 .这就是为什么推断类型是
Product with Serializable with Animal
,因为Animal
没有延伸Product
也没有Serializable
,而case class
隐含了 .要解决此推理,您可以通过
Animal
使类型显式化,也可以使Animal
extendProduct
和Serializable
.Scala中的所有案例类都具有一些属性:
他们将自动扩展
Product
特征,并为他们提供默认实现,因为它们可以被视为a Cartesian Product of N records .他们将扩展
Serializable
,因为它们可以开箱即用(作为设计选择) .它们将具有编译器提供的
hashCode
和equals
的实现,这有助于模式匹配他们将提供
apply
和unapply
方法,用于组合和分解类型 .案例类也是Scala表达Algebraic Data Type的方式,更具体地说是Product Type . Tuples are also a product type,因此他们也扩展了
Product
特征 .当您使用具有共同特征的两个案例类时,scala 's compiler will use it' s类型推断算法尝试为
Array
找到最佳匹配分辨率 .如果您想避免看到此实现细节,可以让您的特征显式扩展这些特征:
所有案例类都自动扩展
Product
和Serializable
. 看起来很难看?是 . 基本上,Product
可以被视为异构集合 . 所有产品类别即 . (Product1,Product2 ...)扩展Product
,其中包含一些常用的方法,如productArity
,productElement
等 .与Case类一样,扩展
Product
的其他类型是List
,Tuple
等从我的scala工作表,
有关详细信息,请查看here .