2010-10-13 17 views
7

Me gustaría escribir un alias tipo para acortar, un código Scala agradable y encapsulado. Supongamos que tengo una colección que tiene la propiedad de ser una lista de mapas, cuyo valor son las tuplas. Mi tipo escribiría algo como List[Map[Int, (String, String)]], o algo más genérico ya que mi aplicación lo permite. Me podría imaginar tener un supertipo pidiendo un Seq[MapLike[Int, Any]] o lo que sea que flote mi bote, siendo las subclases concretas más específicas.Alias ​​tipo Scala, incluido el objeto complementario [principiante]

Entonces me gustaría escribir un alias para este tipo largo.

class ConcreteClass { 
    type DataType = List[Map[Int, (String, String)]] 
    ... 
} 

me permitiría usar sin problemas en todas partes ConcreteClass#DataType puedo tomar uno, y lo utilizan.

Ahora supongamos agrego una función

def foo(a : DataType) { ... } 

y quiero llamar desde el exterior con una lista vacía. Puedo llamar al foo(List()), pero cuando quiero cambiar mi tipo subyacente para que sea otro tipo de Seq, tendré que volver y cambiar también este código. Además, no es muy explícito que esta lista vacía esté destinada a ser DataType. Y el objeto complementario no tiene los métodos asociados List, por lo que no puedo llamar al DataType(), o DataType.empty. Será aún más molesto cuando necesite listas no vacías, ya que tendré que escribir una parte significativa de este tipo largo.

¿Hay alguna manera en que pueda pedirle a Scala que entienda mi tipo como la misma cosa, incluido el objeto complementario con sus métodos de creador, con el interés de acortar el código y el blackboxing? O, cualquier razón por la que no debería estar haciendo esto en primer lugar?

Respuesta

7

La respuesta fue muy simple:

class ConcreteClass { 
    type DataType = List[String] 
} 
object ConcreteClass { 
    val DataType = List 
} 
val d = ConcreteClass.DataType.empty 

Esto permite que el código para llamar ConcreteClass.DataType para construir listas con todos los métodos en la lista y poco esfuerzo.

Muchas gracias a Oleg por la información. Su respuesta también es mejor en caso de que no desee delegar en la lista cualquier llamada a ConcreteClass.DataType, sino que controle con precisión lo que desea que los emisores puedan hacer.

+2

Si no pretendes que las subclases de 'ConcreteClass' reemplacen' DataType', es mejor colocar los alias 'type' y' val' en el objeto complementario (en lugar de tener uno en la clase) Así es como funcionan los alias en el objeto del paquete 'scala'. –

+0

Tienes mucha razón. Haré esto a partir de ahora. Gracias. – Jean

+1

Excepto que d es tipo List [Nothing] – sourcedelica

5

¿Qué tal esto?

 
class ConcreteClass { 
    type DataType = List[String] 
} 
object DataType { 
    def apply(): ConcreteClass#DataType = Nil 
} 
//... 
val a = DataType() 

+0

Esto funciona. Gracias. Sin embargo, con esto tengo que definir cada método de List para hacer lo que quiero, y es un poco detallado. Es muy bueno tener control sobre lo que también se puede llamar. Gracias a su respuesta, creo que obtuve la solución genérica para "llamar a todos los métodos de la Lista": publicarla ahora. Muchas gracias :) – Jean

Cuestiones relacionadas