47 votes

scala et traits sur les instances d'objets

si j'ai un trait:

Je peux l'ajouter à une classe avec "étend":

ou je peux l'ajouter à un nouvel objet quand je le construire:

Mais... puis-je l'ajouter à un objet existant ?

Je charge certains objets en utilisant java et JPA (orm), et je voudrais ajouter quelques fonctionnalités à eux en utilisant des traits. est-il possible?

quelque chose comme:

Merci Fourmi

26voto

Googol Shan Points 592

J'ai une idée pour cette utilisation:

vous pouvez utiliser ce trait comme ci-dessous:

pour votre code d'exemple :

J'espère que ça pourra t'aider.

Actualisé

mais ce modèle a une certaine restriction, vous ne pouvez pas utiliser une méthode d'aide implicite qui a défini déjà.

22voto

axel22 Points 17400

Un temps d'exécution existants objet dans la JVM a une certaine taille sur le tas. L'ajout d'un trait serait en modifiant sa taille sur le tas, et la modification de sa signature.

Donc, la seule façon de procéder serait de faire une sorte de transformation au moment de la compilation.

Composition Mixin en Scala se produit au moment de la compilation. Quel compilateur pourrait potentiellement faire est de créer un wrapper B autour d'un objet existant avec le même type que le fait de simplement renvoyer tous les appels à l'objet existant, puis les mélanger dans un trait T de B. Ceci, cependant, n'est pas mis en œuvre. Il est douteux, lorsque cela serait possible, puisque l'objet A peut être une instance d'une classe final, qui ne peut pas être prolongé.

En résumé, mixin composition n'est pas possible aux instances de l'objet.

Mise à JOUR:

Liés à la smart solution proposée par Googol Shan, et en généralisant, il fonctionne avec n'importe quel trait de caractère, c'est ce que je suis. L'idée est d'extraire la commune mixin fonctionnalité dans l' DynamicMixinCompanion trait. Le client doit alors créer un compagnon objet s'étendant DynamicMixinCompanion pour chaque trait, il veut avoir la dynamique mixin fonctionnalité pour. Ce compagnon de l'objet nécessite de définir les anonymes trait de l'objet est créé (::).

trait DynamicMixinCompanion[TT] {                                                                    
  implicit def baseObject[OT](o: Mixin[OT]): OT = o.obj                                              

  def ::[OT](o: OT): Mixin[OT] with TT                                                               
  class Mixin[OT] protected[DynamicMixinCompanion](val obj: OT)                                      
}                                                                                                    

trait OtherTrait {                                                                                   
  def traitOperation = println("any trait")                                                          
}                                                                                                    

object OtherTrait extends DynamicMixinCompanion[OtherTrait] {                                        
  def ::[T](o: T) = new Mixin(o) with OtherTrait                                                     
}                                                                                                    

object Main {                                                                                        
  def main(args: Array[String]) {                                                                    
    val a = "some string"                                                                            
    val m = a :: OtherTrait                                                                          
    m.traitOperation                                                                                 
    println(m.length)                                                                                
  }                                                                                                  
}                                                                                                    

7voto

Googol Shan Points 592

J'ai l'habitude d'utiliser un `` pour mélanger dans une nouvelle méthode à un objet existant.

Voir, si j'ai un peu de code comme ci-dessous:

et puis vous pouvez utiliser la `` méthode avec un test d'objet déjà existant.

dans votre exemple, vous pouvez utiliser comme ceci:

Je pense à une syntaxe préfet pour définir ce HelperObject:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X