opt*_*nal 21 types scala 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
Run Code Online (Sandbox Code Playgroud)
现在,当我做到以下时:
val x = Array(Dog("Fido"),Cat("Felix"))
Run Code Online (Sandbox Code Playgroud)
它显示结果为:
x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))
Run Code Online (Sandbox Code Playgroud)
虽然我知道案例类与Product trait混在一起
我没有得到的是: Product with Serializable with Animal
据我所知,产品与模式匹配有关
我确实谷歌它,但没有得到任何东西.请帮助我详细了解这个概念.
谢谢
Dan*_*hin 45
这是一种预期的行为,因为它的case class
工作原理.case class
自动extends
两个特征,即Product
和Serializable
.
Product
特征扩展为具有产品类型case class
的代数数据类型.
Serializable
特征被扩展,因此case class
可以被视为纯数据 - 即能够被序列化.
与case class
Dog
和不同Cat
,你的特质Animal
不会延伸Product
或Serializable
.因此,您看到的类型签名.
当你声明类似的东西时Array(Dog(""), Cat(""))
,scalac需要推断出可以代表给定数组的所有元素的单顶类型.
这就是为什么推断类型Product with Serializable with Animal
为Animal
没有扩大Product
,也没有Serializable
,而case class
隐含一样.
要解决这一推论,你可以做类型的露骨Animal
或进行Animal
扩展Product
和Serializable
.
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())
Run Code Online (Sandbox Code Playgroud)
Yuv*_*kov 13
Scala中的所有案例类都具有一些属性:
Product
特征,并为它们提供默认实现,因为它们可被视为N个记录的笛卡尔积.Serializable
因为它们可以开箱即用(作为设计选择).hashCode
和equals
提供,这有助于模式匹配apply
和unapply
方法,用于组合和分解类型.案例类也是Scala表达代数数据类型的方式,更具体地说是产品类型.元组也是一种产品类型,因此它们也扩展了Product
特性.
当您使用具有共同特征的两个案例类时,scala的编译器将使用它的类型推断算法来尝试找到最佳匹配分辨率Array
.
如果您想避免看到此实现细节,可以让您的特征显式扩展这些特征:
sealed trait Animal extends Product with Serializable
Run Code Online (Sandbox Code Playgroud)