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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 08:09:29  来源:igfitidea点击:

Scala case class extending Product with Serializable

scalatypestraitscase-class

提问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两个特征,即ProductSerializable

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 ProductSerializable而 while the case classdid 隐式。

To work around this inference, you can either make type explicit by Animalor make Animalextend Productand Serializable.

要解决此推断,您可以使类型显式通过Animal或使Animal扩展ProductSerializable

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 类都有一些属性:

  1. 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.
  2. They will extend Serializableas they are serializable out of the box (as a design choice).
  3. They will have an implementation of hashCodeand equalsprovided by the compiler, which aids with pattern matching
  4. They will provide applyand unapplymethods, for composition and decomposition of the type.
  1. 它们将自动扩展Producttrait 并为它们提供默认实现,因为它们可以被视为N 条记录的笛卡尔积
  2. 它们将扩展,Serializable因为它们是开箱即用的(作为设计选择)。
  3. 他们将有一个执行hashCodeequals编译器,它与模式匹配提供帮助
  4. 它们将提供applyunapply方法,用于组合和分解类型。

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.

所有案例类都会自动扩展ProductSerializable. 长得丑吗?是的。基本上,Product可以看作是异构集合。所有产品类别即。(产品1,产品2 ...)扩展Product其中包含了一些常用的方法使用像productArityproductElement等等。

Like Case classes other types that extends Productare List,Tupleetc

像案例类的其他类型的扩展ProductListTuple

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.

详情请看这里