2011-09-16 14 views
63

Volviendo a Scala después de un hechizo escrito Haskell, He empezado a utilizar la palabra clave de tipo para hacer mis definiciones de clase un poco más fácil de leer, por ejemplo:tipo Scala palabra clave: la mejor manera de usarlo a través de múltiples clases

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

El problema con el que me he encontrado es que estas definiciones de tipo necesitan vivir dentro de una clase u objeto; no son "ciudadanos de primera clase" como lo son en Haskell. Si trato de definir un tipo fuera de una clase u objeto, obtengo un compilador expected class or object definition.

Mi problema es cómo utilizar estos tipos en varias clases y objetos en un paquete. Lo que he hecho ahora parece bastante feo:

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

Y luego en otro archivo de clase:

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

¿Existe una manera más agradable de hacer esto - y de paso hacen los gurús Scala piensan que es una buena ¿Algo o algo malo que los tipos solo se pueden definir dentro de clases/objetos?

+9

'¿Por qué no utils.RestfulTypes._' importación? – soc

Respuesta

66

¿Funcionará package objects para usted?

Desde el artículo:

Hasta 2,8, lo único que se puede poner en un paquete eran clases, rasgos y objetos independientes. Estas son de lejos las definiciones más comunes que se colocan en el nivel superior de un paquete, pero Scala 2.8 no lo limita a esas. Cualquier clase de definición que pueda incluir dentro de una clase, también puede colocarla en el nivel superior de un paquete. Si tiene algún método de ayuda que le gustaría tener en alcance para un paquete completo, continúe y póngalo en el nivel superior del paquete. Para hacerlo, coloca las definiciones en un objeto de paquete. Cada paquete tiene permitido tener un objeto de paquete. Las definiciones ubicadas en un objeto de paquete se consideran miembros del paquete en sí.

La package object scala ya tiene muchos tipos y valores, por lo que creo que puede utilizar la misma técnica para sus propios tipos.

11

no estoy seguro de lo que constituye la amabilidad en este caso, pero aquí hay dos opciones:

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

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

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

O simplemente importar los miembros del objeto, utilizando con eficacia como un paquete:

import util.RestfulTypes._ 
+1

@agilesteel: el enlace no debe ser el primero, ya que pertenece solo a la primera opción, no modifique el significado de mi respuesta al editar. –

+0

Gracias, el patrón de rasgos desinteresados ​​es muy bueno. Me doy cuenta de que he visto varios frameworks Scala y herramientas que lo usan, simplemente no me di cuenta de lo que era. Gracias de nuevo por la respuesta. –

+0

@Kim: sry, no volverá a suceder. – agilesteel

7

Youn puede usar un objeto de paquete y poner la declaración de tipo allí. Cuando importe ese paquete, la definición de tipo estará disponible.

Un ejemplo:

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

en cuenta que el objeto de paquete tiene el mismo nombre que el paquete con el fin de ser utilizable sin un objeto de prefijo es decir myType.mine Si lo que sea con un nombre diferente, por ejemplo, :

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

se puede acceder con mainType.la mina cuando se importa "paquete"

para más información: http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html

Cuestiones relacionadas