我正在学习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
根据我的理解,产品与模式匹配有关
我确实谷歌了,但没有得到任何东西。请帮助我详细了解这个概念。
谢谢
答案 0 :(得分:37)
由于case class
的工作方式,这是一种预期的行为。 case class
自动extends
两个特征,即Product
和Serializable
。
Product
特征被延长,因为case class
是algebraic data type product 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
明确指明类型,也可以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())
。
((e.Value["NewsOn"]))= DateTime.Now.ToString();
答案 1 :(得分:11)
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的编译器将使用它的类型推断算法来尝试找到Array
的最佳匹配分辨率。
如果您想避免看到此实现细节,可以让您的特征显式扩展这些特征:
sealed trait Animal extends Product with Serializable
答案 2 :(得分:0)
所有案例类都会自动扩展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
详情请见here。