9
votes

Extension d'un trait et de types

J'aimerais avoir un trait scellé qui a une méthode déclarée qui retourne la classe actuelle qui étend le trait. Devrais-je utiliser un type de résumé, un type de paramètre ou y a-t-il une autre belle façon de résoudre ce problème? XXX PRE>

ou P>

case class Bar(name: String) extends Foo[Bar] {
  def doit(other: Bar): Bar = ...
}


0 commentaires

5 Réponses :


1
votes

edit - ci-dessous est ma réponse originale. Votre commentaire indique que vous souhaitez retourner une instance arbitraire d'un type d'assortiment, mais je ne crois pas vraiment que cela soit raisonnable. supposons que c'était, via la syntaxe T.Type : xxx


Ceci est accompli via this.type < / code>: xxx

puis aussi: xxx


3 commentaires

Sonne familier. Pourriez-vous peut-être offrir un exemple de cela?


Cela ne semble pas fonctionner si je veux retourner une nouvelle instance du même type?


Oui - this.type est dépendant du chemin: il est uniquement valide pour renvoyer l'instance actuelle



4
votes

Ils sont surtout interchangeables. Selon Odersky, la raison était principalement de l'exhaustivité: la même chose que le fait que les méthodes et les champs (valeurs) peuvent être abstraits ou passés sous forme de paramètres, afin que les types puissent les types.

Il est préférable d'utiliser un type de résumé lorsque vous souhaitez mélanger plusieurs traits qui utilisent tous le même nom de type. Avec les paramètres de type, vous devez transmettre explicitement le type à chaque

Voici un article expliquant tout cela: http: //www.artima. Com / Weblogs / Viewpost.jsp? thread = 270195


0 commentaires

1
votes
trait Foo[A <: Foo[A]]
This trait can only be mixed in if A is a subtype of Foo[A] and the only type satisfying that is the class Foo is being mixed into. I saw this solution in the Mapper traits in Lift.

1 commentaires

Pas assez. Essayez La barre de classe s'étend FOO [bar] et La classe Baz s'étend FOO [bar] .



2
votes

Vous pouvez écrire: xxx

La différence à votre exemple est que la barre ne peut être instanciée d'une autre manière (par exemple, la barre de la classe (nom: la chaîne) s'étend foo [String] ).


0 commentaires

2
votes

Vous pouvez réduire quelque peu sur la répétition par la méthode de votre DOIT code> Renvoyez une fonction d'usine:

trait Foo { 
   self: T => // won't compile because T isn't defined yet
   type T 
   def doit: T => T
}


0 commentaires