web-dev-qa-db-fra.com

Etui Scala classe extensible Produit avec Serializable

J'apprends le scala et j'essaie de suivre le formulaire Scala Cookbook:

trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal

Maintenant, quand j'ai fait en tant que:

val x = Array(Dog("Fido"),Cat("Felix"))

il montre le résultat comme:

x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))

Bien que je sache qu'une classe de cas est mélangée à un trait de produit

Ce que je ne comprends pas, c'est: Product with Serializable with Animal

Selon ma compréhension, le produit a quelque chose à voir avec l'appariement de motifs

Je l'ai fait sur Google mais je n'ai rien obtenu.Veuillez m'aider à comprendre le concept en détail.

Merci 

16
optional

Ceci est un comportement attendu en raison du fonctionnement de case class. case class automatiquement extends deux traits, à savoir Product et Serializable

Product trait est étendu car case class est un type de données algébrique avec type de produit .

Serializable trait est étendu de sorte que case class puisse être traité comme une donnée pure, c'est-à-dire capable d'être sérialisé.

Contrairement à case classDog et Cat, votre trait Animal ne s'étend pas Product ou Serializable. D'où la signature de type que vous voyez.

Lorsque vous déclarez quelque chose comme Array(Dog(""), Cat("")), scalac doit déduire un seul type top pouvant représenter tous les éléments d'un tableau donné. 

C'est pourquoi le type inféré est Product with Serializable with Animal car Animal n'a pas été étendu Product ni Serializable alors que le case class l'a été implicitement.

Pour contourner cette inférence, vous pouvez rendre le type explicite par Animal ou rendre Animal extend Product et 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())
37
Daniel Shin

Toutes les classes de cas à Scala possèdent quelques propriétés:

  1. Ils étendront automatiquement le trait Product et une implémentation par défaut leur sera fournie, car ils peuvent être vus comme un produit cartésien de N enregistrements
  2. Ils étendront Serializable car ils sont sérialisables dès l’origine (en tant que choix de conception). 
  3. Ils auront une implémentation de hashCode et equals fournie par le compilateur, ce qui facilite la recherche de modèles
  4. Ils fourniront des méthodes apply et unapply, pour la composition et la décomposition du type.

Les classes de cas sont également la manière dont Scala exprime un type de données algébrique , plus précisément un type de produit . Les n-uplets sont aussi un type de produit }, et ainsi ils étendent également le trait Product.

Lorsque vous utilisez deux classes de cas avec un trait commun, le compilateur de scala utilisera son algorithme d'inférence de type pour tenter de trouver la meilleure résolution de correspondance pour Array

Si vous souhaitez éviter de voir ce détail d'implémentation, vous pouvez demander à votre trait d'étendre explicitement ces traits:

sealed trait Animal extends Product with Serializable
11
Yuval Itzchakov

Toutes les classes de cas s'étendent automatiquement Product et Serializable. C'est moche? oui . Fondamentalement, Product peut être considéré comme une collection hétérogène. Toutes les classes de produits à savoir. (Product1, Product2 ...) étend Product qui contient certaines méthodes courantes à utiliser comme productArity, productElement etc.

Comme les classes de cas, les autres types qui développent Product sont List, Tuple etc.

De ma feuille de travail 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

Pour plus de détails, regardez ici .

0
Som Bhattacharyya