Scala 案例类使用可序列化扩展产品
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36525804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala case class extending Product with Serializable
提问by optional
I am learning scala and tried following form Scala Cookbook:
我正在学习 Scala 并尝试使用以下表格 Scala Cookbook:
trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal
Now when I did following as :
现在,当我执行以下操作时:
val x = Array(Dog("Fido"),Cat("Felix"))
it show result as :
结果显示为:
x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))
Although I know that a case class is mixed in with Product trait
虽然我知道案例类与产品特征混合在一起
What I am not getting is : Product with Serializable with Animal
我没有得到的是: Product with Serializable with Animal
As per my understanding Product has something to do with Pattern matching
根据我的理解产品与模式匹配有关
I did google it but didn't get anything.Please Help to get me the concept in detail.
我确实用谷歌搜索过但没有得到任何东西。请帮助我详细了解这个概念。
Thanks
谢谢
回答by Daniel Shin
This is an expected behavior because of how case classworks. case classautomatically extendstwo traits, namely Productand Serializable.
由于case class工作原理,这是预期的行为。case class自动extends两个特征,即Product和Serializable。
Producttrait is extended as case classis an algebraic data typewith product type.
Producttrait 被扩展为具有产品类型case class的代数数据类型。
Serializabletrait is extended so that case classcan be treated as a pure data - i.e capable of being serialized.
Serializabletrait 被扩展,以便case class可以被视为纯数据 - 即能够被序列化。
Unlike case classDogand Cat, your trait Animaldoes not extend Productor Serializable. Hence the type signature you see.
与case classDogand不同Cat,您的 traitAnimal不扩展Productor Serializable。因此,您看到的类型签名。
When you declare something like Array(Dog(""), Cat("")), scalac needs to infer single top typethat can represent all the elements of given array.
当你声明类似的东西时Array(Dog(""), Cat("")),scalac 需要推断可以表示给定数组的所有元素的单一顶部类型。
That's why the inferred type is Product with Serializable with Animalas Animaldid not extend Productnor Serializablewhile the case classdid implicitly.
这就是为什么推断的类型Product with Serializable with Animalas Animaldid not extend Product,Serializable而 while the case classdid 隐式。
To work around this inference, you can either make type explicit by Animalor make Animalextend Productand Serializable.
要解决此推断,您可以使类型显式通过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())
回答by Yuval Itzchakov
All case classes in Scala posses a few properties:
Scala 中的所有 case 类都有一些属性:
- They will automatically extend the
Producttrait and a default implementation will be provided for them, as they can be viewed as a Cartesian Product of N records. - They will extend
Serializableas they are serializable out of the box (as a design choice). - They will have an implementation of
hashCodeandequalsprovided by the compiler, which aids with pattern matching - They will provide
applyandunapplymethods, for composition and decomposition of the type.
- 它们将自动扩展
Producttrait 并为它们提供默认实现,因为它们可以被视为N 条记录的笛卡尔积。 - 它们将扩展,
Serializable因为它们是开箱即用的(作为设计选择)。 - 他们将有一个执行
hashCode和equals编译器,它与模式匹配提供帮助 - 它们将提供
apply和unapply方法,用于组合和分解类型。
Case classes are also Scala's way of expressing an Algebraic Data Type, more specifically a Product Type. Tuples are also a product type, and as so they also extend the Producttrait.
Case 类也是 Scala 表达代数数据类型,更具体地说是产品类型的方式。元组也是一种产品类型,因此它们也扩展了Product特征。
When you use two case classes with a common trait, the scala's compiler will use it's type inference algorithm to attempt to find the best matching resolution for the Array.
当您使用具有共同特征的两个 case 类时,scala 的编译器将使用它的类型推断算法来尝试为Array.
If you want to avoid seeing this implementation detail, you can have your trait explicitly extend those traits:
如果你想避免看到这个实现细节,你可以让你的 trait 显式扩展这些 trait:
sealed trait Animal extends Product with Serializable
回答by Som Bhattacharyya
All case classes automatically extend Productand Serializable. It looks ugly ? yes.
Basically ,Productcan be viewed as heterogeneous collections. All Product classes viz. (Product1 , Product2 ...) extends Productwhich contains some common methods to use like productArity, productElementetc.
所有案例类都会自动扩展Product和Serializable. 长得丑吗?是的。基本上,Product可以看作是异构集合。所有产品类别即。(产品1,产品2 ...)扩展Product其中包含了一些常用的方法使用像productArity,productElement等等。
Like Case classes other types that extends Productare List,Tupleetc
像案例类的其他类型的扩展Product是List,Tuple等
From my scala worksheet,
从我的 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
For details look here.
详情请看这里。

