[英]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
两个特征,即Product
和Serializable
。
Product
trait 被扩展为case class
是具有product type的代数数据类型。
Serializable
trait 得到了扩展,因此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())
Scala 中的所有 case 类都有一些属性:
Product
trait 并为它们提供默认实现,因为它们可以被视为N 条记录的笛卡尔积。Serializable
因为它们是开箱即用的(作为设计选择)。hashCode
和equals
的实现,这有助于模式匹配apply
和unapply
方法,用于类型的组合和分解。 Case 类也是 Scala 表达代数数据类型,更具体地说是产品类型的方式。 元组也是一种产品类型,因此它们也扩展了Product
特性。
当您使用具有共同特征的两个 case 类时,scala 的编译器将使用它的类型推断算法来尝试找到Array
的T
类型的最小上限 (LUB)。 由于这两个 case 类都通过编译器扩展了Product
和Serializable
,而trait
没有,它会在搜索过程中将其应用到最终的计算类型。
如果你想避免看到这种情况,你可以让你的 trait 显式扩展这些 trait:
sealed trait Animal extends Product with Serializable
所有 case 类都会自动扩展Product
和Serializable
。 长得难看? 是的。 基本上, Product
可以被视为异构集合。 所有产品类别即。 (Product1 , Product2 ...) 扩展Product
,其中包含一些常用方法,如productArity
、 productElement
等。
与 Case 类一样,扩展Product
其他类型是List
、 Tuple
等
从我的 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.