Allgemeiner Parametertyp, der void akzeptiert

8

Ich versuche, eine API für ein Open-Source-Projekt zu erstellen, an dem ich arbeite, und ich habe eine Geschwindigkeitsblase bei der Erweiterung der API erreicht, während die Semantik konsistent mit der aktuellen API geblieben ist. Ich möchte eine Methodensignatur mit einem generischen Parameter definieren können, der das Ergebnis des Aufrufs der beliebigen Methodensignatur akzeptiert. Mit " any " ist gemeint, dass void Methoden eingeschlossen werden sollen. Ich weiß bereits, dass Sie Parametertypen von void nicht direkt definieren können - bitte wiederholen Sie nicht die offensichtliche Tatsache. Was nicht offensichtlich ist, ist, ob es einen Trick gibt, mit dem ein void -Methodenaufruf als ein Argument für eine Methode bereitgestellt werden kann (d. H. Und ignoriert werden kann).

Back Geschichte, so macht das ein wenig mehr Sinn, warum ich so etwas tun möchte, und was mein Design Ziel und Einschränkungen sind, falls das obige unmöglich ist (wie ich fürchte):

Meine aktuelle API definiert ein sehr wiederholbares Muster von Methoden wie folgt:

%Vor%

Wie die Namen andeuten, werden die Parameter ignoriert und in der Implementierung nicht einmal verwendet. In der Verwendung wird ignoredRetVal durch einen Methodenaufruf an einen dynamischen Proxy ersetzt. Da Parameter vor dem Aufruf der Methode ausgewertet werden, wird diese dynamische Proxy-Methode vor der äußeren Funktion aufgerufen ( functionFor oder predicateFor , etc.). Der dynamische Proxyaufruf zeichnet die aufgerufene Method (oder Methodenkette) auf und konvertiert diese in ein Function -Objekt (Guava) oder ein anderes funktionsähnliches Objekt aus mehreren funktionalen Bibliotheken.

Ich versuche jetzt, eine ähnliche Semantik zu erstellen, die Methodenaufrufe erfasst, die nur für Nebeneffekte verwendet werden, ohne dass ein Rückgabetyp erforderlich ist (z. B. Functional Java's Effect Wenn ein void-Rückgabetyp angegeben wird, wird er ebenfalls ignoriert und akzeptiert.Der Schlüssel ist, dass die Semantik irgendwie erzwingen muss, dass die Proxy-Methode aufgerufen wird, bevor eine andere Methode den abgefangenen Proxy extrahiert Methoden-Aufrufe, und da wir nur an Nebenwirkungen interessiert sind, enthalten die Kandidatenmethoden wahrscheinlich void -Methoden. Im Idealfall würde es so aussehen:

%Vor%

(was bereits für nicht-void Rückgabetypen funktioniert) und könnte wie folgt verwendet werden:

%Vor%

Wie ich gesagt habe, fürchte ich, dass die gesuchte Semantik nicht direkt unterstützbar ist. Wenn nicht, dann sollte jede Alternative dem von mir festgelegten Muster nahe kommen. Außerdem war das Ziel meiner API, das "vertikale Rauschen" von Implementierungen der inneren Klassen zu reduzieren, und ich bin kein Fan von Double Brace Initialisern. Welche Vorschläge auch immer angeboten werden, ich suche nach einer Semantik, die die Kürze unterstützt, insbesondere eine Semantik mit einer einzigen Aussage.

    
Kevin Welker 27.08.2012, 04:50
quelle

1 Antwort

1

Ich glaube nicht, dass Sie jemals einen void in einen Ausdruck einbringen können, besonders wenn Sie den Double-Brace-Hack nicht mögen.

Sie könnten Mockitos Beispiel in Ihrem API-Design folgen. Normalerweise richten Sie einen Mock so ein:

%Vor%

Aber für eine Leere tun Sie das:

%Vor%

Ebenso können Sie die Methoden von Effect<T> aufzählen, um sie zu statischen Methoden Ihrer Bibliothek zu machen.

z. Wenn Effect<T> doSomething() hat, dann würden Sie es wie

invertieren %Vor%

Dies setzt jedoch voraus, dass die relevanten Methoden von Effect<T> selbst keinen Wert zurückgeben.

Wenn das keine Option ist und Sie Effect<T> benötigen, können Sie es statusbehaftet machen, etwa so:

%Vor%

Wo VoidEffect<T> implementiert Effect<Void> und on() gibt den übergebenen Proxy zurück (oder einen anderen Proxy). Dann würdest du IllegalStateException werfen wollen, wenn on() nicht aufgerufen wurde, bevor du sonst mit effect interagierst.

    
Mark Peters 27.08.2012, 05:11
quelle

Tags und Links