Question

Je voudrais écrire un alias de type d'écourter, agréable et le code Scala encapsulé. Supposons que je suis une collection qui a la propriété d'être une liste de cartes, dont la valeur sont tuples. Mon type écrirait quelque chose comme List[Map[Int, (String, String)]], ou quoi que ce soit mon application plus générique permet. Je pouvais imaginer avoir un supertype demander un Seq[MapLike[Int, Any]] ou quoi que mon bateau flotte, avec des sous-classes de béton étant plus précis.

Je veux alors d'écrire un alias pour ce type long.

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

Je puis heureusement utiliser ConcreteClass#DataType partout où je peux prendre un, et l'utiliser.

Supposons maintenant que j'ajoute une fonction

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

Et je veux l'appeler de l'extérieur avec une liste vide. Je peux appeler foo(List()), mais quand je veux changer mon type sous-jacent à un autre type de Seq, je vais devoir revenir et changer ce code aussi. Par ailleurs, il est pas très explicite cette liste vide est conçue comme un DataType. Et l'objet compagnon n'a pas les méthodes de List associées, donc je ne peux pas appeler DataType() ou DataType.empty. Ça va être encore plus gênant quand j'ai besoin des listes non vides puisque je vais devoir écrire une partie importante de ce type long.

Est-il possible que je peux demander à Scala de comprendre mon type que la même chose, y compris objet compagnon avec ses méthodes de créateur, dans l'intérêt du Code et le raccourcissement blackboxing il? Ou, une raison pour laquelle je ne devrais pas faire cela en premier lieu?

Était-ce utile?

La solution

La réponse est en fait assez simple:

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

Cela permet à mon code d'appeler ConcreteClass.DataType aux listes de construct avec toutes les méthodes de liste et peu d'effort.

Merci beaucoup à Oleg pour la perspicacité. Sa réponse est également préférable si vous souhaitez ne pas déléguer à la liste tout appel à ConcreteClass.DataType, mais le contrôle avec précision ce que vous voulez permettre aux appelants de faire.

Autres conseils

Qu'en est-ce?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top