Domanda

Mi piacerebbe scrivere un tipo di alias per abbreviare, bello e codice Scala incapsulato. Supponiamo che io avuto qualche collezione che ha la proprietà di essere un elenco di mappe, il cui valore sono tuple. Il mio tipo avrebbe scritto qualcosa di simile List[Map[Int, (String, String)]], o qualcosa di più generico come la mia domanda lo permette. Potrei immaginare di avere un supertipo chiedere un Seq[MapLike[Int, Any]] o qualsiasi altra cosa galleggia la mia barca, con sottoclassi concrete di essere più specifico.

Mi piacerebbe poi voglio scrivere un alias per questo tipo lungo.

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

Vorrei poi felicemente utilizzare ConcreteClass#DataType ovunque posso prendere uno, e usarlo.

Ora supponiamo che io aggiungo una funzione

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

E voglio chiamarlo da fuori con una lista vuota. Posso chiamare foo(List()), ma quando voglio cambiare il mio tipo sottostante di essere un altro tipo di Seq, dovrò tornare indietro e modificare il codice troppo. Inoltre, non è molto esplicito questo elenco vuoto è inteso come un DataType. E l'oggetto associato non ha i metodi List associati, quindi non posso chiamare DataType(), o DataType.empty. E 'intenzione di essere ancora più fastidioso quando ho bisogno di liste non vuote in quanto dovrò scrivere una parte significativa di questo tipo lungo.

C'è un modo posso chiedere Scala di capire il mio tipo, come la stessa cosa, tra cui oggetto associato con i suoi metodi creatore, nell'interesse di abbreviare codice e blackboxing esso? Oppure, alcuna ragione per cui non dovrei fare questo, in primo luogo?

È stato utile?

Soluzione

La risposta è stata molto semplice:

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

In questo modo, il mio codice per chiamare ConcreteClass.DataType alle liste costrutto con tutti i metodi di List e poco sforzo.

Grazie mille a Oleg per l'intuizione. La sua risposta è anche meglio nel caso in cui si desidera di non delegare a Lista qualsiasi chiamata a ConcreteClass.DataType, ma il controllo esattamente ciò che si vuole consentire ai chiamanti da fare.

Altri suggerimenti

Che dire di questo?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top