2016-04-10 27 views
13

Sto imparando scala e ho cercato seguente modulo Scala Cookbook:Scala caso Classe prodotto allungabile con Serializable

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

Ora, quando ho seguito come:

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

si visualizza il risultato come:

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

Anche se so che una classe di case è stata miscelata con il tratto di prodotto

Quello che non sto ottenendo è: Product with Serializable with Animal

Come per la mia comprensione del prodotto ha qualcosa a che fare con il modello di corrispondenza

ho fatto google, ma non ha ottenuto anything.Please Aiuto per farmi avere il concetto in dettaglio.

Grazie

+0

Ehi, è una matrice eterogenea ed entrambi gli elementi si estendono per l'animale, quindi con l'animale. Se si inseriscono entrambe queste classi di casi all'interno di un'altra classe di case, quindi si aggiunge la classe case all'array. otterresti la matrice della classe del caso. Ero io stesso alla ricerca di una buona lettura di questo prodotto con la parte posteriore serializzabile .. Ma non l'ho trovato. Forse qualcuno può cancellare i nostri pensieri.! –

+0

http://underscore.io/blog/posts/2015/06/04/more-on-sealed.html –

+0

anche https://github.com/scala/scala-abide/issues/41 –

risposta

25

Questo è un comportamento previsto a causa di come funziona case class. case class automaticamente extends due tratti, ovvero Product e Serializable.

Product tratto esteso come case class è un algebraic data type con product type.

Serializable tratto è esteso in modo che case class può essere trattato come un puro dati - cioè in grado di essere serializzato.

differenza case classDog e Cat, il tuo tratto Animal non si estende Product o Serializable. Da qui il tipo di firma che vedi.

Quando si dichiara qualcosa come Array(Dog(""), Cat("")), scalac deve dedurre il singolo top type che può rappresentare tutti gli elementi di un determinato array.

Ecco perché il tipo derivato è Product with Serializable with Animal come Animal non estendere ProductSerializable mentre il case class fatto implicitamente.

Per aggirare questa inferenza, è possibile effettuare tipo esplicita Animal o fare Animal estendono Product e 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()) 
+2

Grazie per la spiegazione e i collegamenti wiki che mi hanno chiarito con il modello matematico. – optional

9

Tutte le classi case a Scala possiedono alcune proprietà:

  1. Essi si estenderà automaticamente il Product tratto e un'implementazione di default saranno previste per loro, in quanto possono essere visti come a Cartesian Product of N records.
  2. Si estenderanno Serializable poiché sono serializzabili fuori dalla scatola (come scelta di progettazione).
  3. Esse avranno un'implementazione di hashCode e equals fornito dal compilatore, che aiuta con pattern matching
  4. Essi fornirà apply e unapply metodi, per composizione e scomposizione del tipo.

Le classi di casi sono anche il modo in cui Scala esprime un Algebraic Data Type, in particolare uno Product Type. Tuples are also a product type e, così facendo, estendono anche il tratto Product.

Quando si utilizzano due case case con un tratto comune, il compilatore di scala utilizzerà il suo algoritmo di inferenza del tipo per tentare di trovare la migliore risoluzione di corrispondenza per lo Array.

Se si vuole evitare di vedere questo dettaglio di implementazione, si può avere la caratteristica estendere esplicitamente quei tratti:

sealed trait Animal extends Product with Serializable 
0

Tutte le classi case si estendono automaticamente Product e Serializable. Sembra brutto? sì. Fondamentalmente, Product possono essere visualizzati come raccolte eterogenee. Tutte le classi di prodotto vale. (Prodotto1, Prodotto2 ...) estende Product che contiene alcuni metodi comuni da utilizzare come productArity, productElement ecc.

classi come il caso di altri tipi che si estende Product sono List, Tuple ecc

Dal mio Scala foglio di lavoro,

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 

Per i dettagli sembrano here.

Problemi correlati