2010-11-10 8 views
4

La suite example de Un tour de Scala montre comment implicite peut être utilisé pour fournir les membres manquants appropriés (ajouter et unité) en fonction du type. Le compilateur choisira le bon objet implicite dans la portée. La bibliothèque utilise également cela avec List.sortBy et Ordering ou List.sum et Numeric par exemple.Utilisations valides des paramètres implicites

est cependant l'utilisation suivante en classe B une utilisation valide/recommandée des paramètres implicites (par opposition à ne pas utiliser implicite dans la classe A):

class I 

class A { 
    def foo(i:I) { bar(i) } 
    def bar(i:I) { baz(i) } 
    def baz(i:I) { println("A baz " + i) } 
} 
(new A).foo(new I) 

class B { 
    def foo(implicit i:I) { bar } 
    def bar(implicit i:I) { baz } 
    def baz(implicit i:I) { println("B baz " + i) } 
} 
(new B).foo(new I) 

Là où je l'utilise principalement l'implicite pour me sauver de la frappe sur le site d'appel lors du passage d'un paramètre le long de la pile.

+1

Bien que valide selon les règles de la langue, personnellement, je ne voudrais pas utiliser implicits pour ces situations. Je les utiliserais pour: 1) Modifier le comportement d'une méthode en fonction de l'environnement appelant. 2) Imposer une exigence sur l'appel qui dépend du paramètre de type de la classe qui l'entoure ou de la méthode elle-même. Mais, c'est juste mon point de vue personnel quand et comment ils devraient être utilisés. Peut-être existe-t-il d'autres modèles valides et utiles. – axel22

Répondre

3

C'est un très bon cas d'utilisation. Je recommande réellement ceci quand la portée détermine le paramètre à utiliser. Il fournit un moyen élégant de transmettre une sorte de contexte dans une classe Plugin afin que les fonctions utilitaires utilisent le contexte. Par exemple:

trait Context 

object UtilityLib { 
    def performHandyFunction(implicit x : Context) : SomeResult = ... 
} 

trait Plugin { 
    def doYourThing(implicit ctx : Context) : Unit 
} 

class MyPlugin extends Plugin { 
    def doYourThing(implicit ctx : Context) : Unit = { 
    UtilityLib.performHandyFunction 
    } 
} 

SomePluginAPI.register(new MyPlugin) 

Vous pouvez voir un exemple dans un database migration system I was toying. Découvrez la classe Migration et son MigrationContext.

+0

Oui, je peux voir comment cela est utile. Le cas d'utilisation qui a suscité la question est en quelque sorte le même, même si je n'ai pas pensé au mot «contexte» ... – huynhjl

2

Cela ne ressemble pas vraiment à une utilisation idiomatique d'implicits, qui tendent à être adaptés aux classes de types et à l'injection de dépendances. Il n'y a absolument aucune raison de passer sur une classe sans membres ...

Il est également plus fréquent de définir un val implicite ou objet de type I avant de faire l'appel à (new B).foo

Ceci étant dit, vous avez fourni un exemple évidemment très abstrait. Donc, il n'est pas trop difficile d'imaginer un cas d'utilisation raisonnable pour implicits qui suit un modèle similaire.