2012-08-23 19 views
7

Ich habe eine Methode, die einige andere Methoden aufruft, die ein implizites vom Typ Foo verwenden. Ich möchte f implizit in Foo machen. Dies ist, wie ich es tun:Ein implizites Argument innerhalb einer Methode markieren

def myMethod(a: Int, f: Foo) = { 
    implicit val implicitF = f; 
    somethingThatNeedsFoo(a) 
} 

Ich will nicht f implizit in der Signatur von myMethod markieren, da Foos nicht implizit im Kontext ist die myMethod verwendet werden. Meine Frage: Gibt es einen eher idiomatischen (oder prägnanten) Weg, diesen Effekt zu erreichen, als eine temporäre Variable zu verwenden?

+2

In diesem einfachen Beispiel ist es wahrscheinlich einfacher, "f" explizit zu übergeben, anstatt implicits zu verwenden - aber ich gehe davon aus, dass Ihr realer Code komplex genug ist, um das Implizite sinnvoll zu machen. In diesem Fall denke ich, dass Ihre Lösung, innerhalb der Methode ein "implizites val" zu deklarieren, der beste Weg ist, dies zu tun, wenn Sie vermeiden wollen, dass der Parameter selbst als implizit in der Methodensignatur deklariert wird. – DaoWen

+0

@DaoWen Sie sollten wirklich Ihren Kommentar als Antwort einreichen. –

+0

@Aaron Novstrup - Yeah, schau auf die anderen Antworten, die ich wahrscheinlich haben sollte. Ich bin immer noch ziemlich neu hier, also fällt es mir immer noch schwer zu entscheiden, was in die Kategorie Antwort/Kommentar fällt. – DaoWen

Antwort

4

Sie können implizite Parameter explizit übergeben. Obwohl der implizite Bereich des Aufrufers kein Foo enthält, kann der Aufrufer sie nur explizit übergeben.

Wie kommentiert, können Sie diesen gleichen Trick verwenden, um die Foo somethingThatNeedsFoo weitergeben müssen:

def myMethod(a: Int, f: Foo) = 
    somethingThatNeedsFoo(a)(f) 
6

Ich habe das tatsächlich verwendet wird, nie gesehen, aber Sie können verbindlich die Variable auf einen Namen vermeiden. Natürlich mit dem Unterstrich:

implicit val _ = f 

Ich würde jedoch von dieser Verwendung abraten.

+0

Was ist der Grund, von dieser Verwendung abzuraten? Ich mag, dass es vermeidet, den lokalen Namespace mit einem Bezeichner zu beschmutzen, der niemals verwendet wird, und es ist weniger "Rauschen" im Code. Mögliche verwirrende Compilerfehler? –

+1

Ich denke, dass es verwirrend sein könnte, weil der Unterstrich auch als "implizit ignorieren/deaktivieren" wahrgenommen werden könnte. (Wie in 'Import Predef. {Any2stringadd => _, _}'.) – Debilski

Verwandte Themen