web-dev-qa-db-ja.com

Scala SerializableでProductを拡張するケースクラス

私は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

私の理解によると、製品はパターンマッチングと関係があります

私はそれをグーグルで調べましたが、何も得られませんでした。コンセプトを詳しく知るために助けてください。

ありがとう

16
optional

_case class_の動作方法により、これは予期される動作です。 _case class_自動的にextendsの2つの特性、つまりProductSerializable

Product特性は、_case class_が 代数データ型製品型 であるため拡張されます。

Serializable特性は、_case class_を純粋なデータとして扱うことができるように拡張されています。つまり、シリアル化が可能です。

_case class_ DogおよびCatとは異なり、特性AnimalProductまたはSerializableを拡張しません。したがって、表示されるタイプシグネチャ。

Array(Dog(""), Cat(""))のようなものを宣言する場合、scalacは特定の配列のすべての要素を表すことができる単一の top type を推論する必要があります。

AnimalProductSerializableを拡張しなかったが、_Product with Serializable with Animal_は暗黙的に拡張したので、推論された型は_case class_である。

この推論を回避するには、Animalでタイプを明示的にするか、AnimalProductSerializableに拡張します。

_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())
_
37
Daniel Shin

Scala=のすべてのケースクラスには、いくつかのプロパティがあります。

  1. これらはProduct特性を自動的に拡張し、 Nレコードのデカルト積 として表示できるため、デフォルトの実装が提供されます。
  2. それらはSerializableを拡張します(設計上の選択として)そのままシリアル化できるためです。
  3. これらには、コンパイラーによって提供されるhashCodeequalsの実装があり、パターンマッチングを支援します。
  4. 型の構成と分解のために、applyメソッドとunapplyメソッドを提供します。

ケースクラスは、Scalaの 代数データ型 、より具体的には 製品型 の表現方法でもあります。 タプルは製品タイプでもあります であるため、Product特性も拡張します。

共通の特性を持つ2つのケースクラスを使用する場合、scalaのコンパイラはその型推論アルゴリズムを使用して、Arrayに最適な解像度を見つけようとします。

この実装の詳細を見ることを避けたい場合は、あなたの特性にそれらの特性を明示的に拡張させることができます:

sealed trait Animal extends Product with Serializable
11
Yuval Itzchakov

すべてのケースクラスは、ProductおよびSerializableを自動的に拡張します。見苦しい?はい。基本的に、Productは異種コレクションとして表示できます。すべての製品クラス。 (Product1、Product2 ...)は、ProductproductArityなどのように使用する一般的なメソッドを含むproductElementを拡張します。

Caseクラスと同様に、Productを拡張する他の型はListTupleなどです。

私の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

詳細については、 こちら をご覧ください。

0