2011-09-16 13 views
63

Tornando alla Scala dopo un periodo di scrittura a Haskell, ho iniziato ad usare la parola chiave tipo per fare le mie definizioni di classe un po 'più leggibile, ad esempio:Scala Tipo di parola chiave: il modo migliore per usarlo su più classi

type RestfulParams = Map[String, String] 
def canonicalize(params: RestfulParams): String = { ... } 

Il problema che ho incontrato è che queste definizioni di tipo devono vivere all'interno di una classe o di un oggetto - non sono "cittadini di prima classe" come se fossero in Haskell. Se provo a definire un tipo al di fuori di una classe o di un oggetto, ottengo un compilatore expected class or object definition.

Il mio problema è quindi come utilizzare questi tipi su più classi e oggetti in un pacchetto? Quello che ho fatto ora sembra abbastanza brutto:

object RestfulTypes { type RestfulParams = Map[String, String] etc } 

E poi in un altro file di classe:

import utils.{RestfulTypes => RT} 
def get(resource: String, params: RT.RestfulParams): String = { ... } 

C'è un modo migliore di fare questo - e per inciso non i guru Scala pensano che sia una buona cosa o cosa brutta che i tipi possono essere definiti solo all'interno di classi/oggetti?

+9

Perché non 'import utils.RestfulTypes._'? – soc

risposta

66

package objects lavoro per voi?

Dall'articolo:

Fino 2.8, le uniche cose che si possono mettere in un pacchetto erano le classi, i tratti e oggetti autonomi. Queste sono di gran lunga le definizioni più comuni che sono poste al livello più alto di un pacchetto, ma Scala 2.8 non ti limita solo a quelle. Qualsiasi tipo di definizione che puoi inserire in una classe, puoi anche metterlo al livello più alto di un pacchetto. Se hai qualche metodo di supporto che vorresti avere nell'ambito di un intero pacchetto, vai avanti e mettilo nel livello più alto del pacchetto. Per fare ciò, inserisci le definizioni in un oggetto pacchetto. Ogni pacchetto può avere un oggetto pacchetto. Tutte le definizioni inserite in un oggetto pacchetto sono considerate membri del pacchetto stesso.

Il package object scala ha già molti tipi e valori, quindi penso che sia possibile utilizzare la stessa tecnica per i propri tipi.

11

non sono sicuro di ciò che costituisce gentilezza in questo caso, ma qui ci sono due opzioni:

Usando un tratto: (Scala's Selfless Trait Pattern)

trait RestfulTypes { 
    type Params = Map[String,String] 
    //... 
} 

object MyRestService extends RestService with RestfulTypes { /* ... */ } 

O semplicemente importare i membri dell'oggetto, in modo efficace ad usarlo come un pacchetto:

import util.RestfulTypes._ 
+1

@agilesteel: il collegamento non deve essere il primo poiché appartiene solo alla prima opzione, non modificare il significato della mia risposta durante la modifica. –

+0

Grazie, il modello del tratto altruistico è molto bello. Mi rendo conto di aver visto vari framework e strumenti di Scala che lo utilizzano, ma non ho capito cosa fosse. Grazie ancora per la risposta. –

+0

@Kim: sry, non succederà più. – agilesteel

7

Youn può utilizzare un oggetto pacchetto e inserire la dichiarazione del tipo lì. Quando si importa quel pacchetto, la definizione del tipo sarà disponibile.

Un esempio:

//package myType 
package object myType {type mine = List[String]} 

noti che l'oggetto del pacchetto ha lo stesso nome del pacchetto in modo da essere utilizzabile senza un oggetto prefisso cioè myType.mine Se si nome con un nome diverso per esempio :

//package myType 
package object mainType {type mine = List[String]} 

accessibile con mainType.mio quando si importano "pacchetto"

per ulteriori informazioni: http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html

Problemi correlati