Ich habe Code, der die Invariante hat, dass ein Objekt in der Funktion konstruiert werden muss, in der es letztendlich verwendet wird (aus verschiedenen Gründen, die mit dem globalen Zustand zusammenhängen, die nicht ideal sind, aber Teil der Annahme sind).
z.B. Angenommen, es gibt die Funktion boo unten, die für die Manipulation von moo verantwortlich ist.
%Vor%Clients von boo, die boo verwenden wollen, müssen einen Typ von () = & gt; Moo, wo die Funktion das gewünschte Moo generiert.
Ideales Clientverhalten:
%Vor%Das Moo wird erst im Inneren des Buhkörpers erstellt.
Ein Client kann jedoch leicht mit dem folgenden Code einen Fehler machen:
%Vor%Dies bricht die Invariante, wo die moo-Konstruktion nur in boo auftreten soll.
Im Grunde genommen möchte ich feststellen, ob der Rückgabewert von mooGen innerhalb des Aufruf-Stacks der Funktion erzeugt wird oder ob er vorher erstellt wurde.
Es gibt viele Möglichkeiten, dies zur Laufzeit zu überprüfen. Gibt es jedoch eine Möglichkeit, dieses Muster zu compile Zeit zu erzwingen? Verwenden Sie implicits oder etwas anderes clever?
Irgendwelche Ideen werden geschätzt!
Setzen Sie boo und Moo in ihr eigenes Objekt zusammen mit einer Tokenklasse, die nicht außerhalb des Objekts instanziiert werden kann.
%Vor%Nun, was Sie wollen, kann getan werden:
%Vor%Und was Sie nicht wollen, kann nicht getan werden:
%Vor%Aber wenn der Klient wirklich will kann er - leider - immer noch sein Moo:
%Vor% Ich nehme an, wenn sowohl der Konstruktor von Moo
als auch die Methode boo
unter Ihrer Kontrolle stehen und nicht von Clients geschrieben werden müssen, dann können Sie Moo
einen impliziten Parameter nehmen und diesen arrangieren die einzige Stelle, an der sich ein geeigneter impliziter Wert befindet, ist in boo
.
Es ist nicht ideal ... und Sie können möglicherweise den Typ des impliziten Parameters nicht vollständig privat machen (was es viel sicherer machen würde, dass der Client keine Moo
außerhalb von boo
instanziiert ), weil ich vermute, dass der Compiler über einen privaten Typ klagen wird, der in der Definition von Moo
durchsickert. Aber auch ohne das sollte es Ihnen zumindest helfen, die versehentliche Erstellung von Moo
s außerhalb von boo
zu verhindern; Der Client müsste absichtlich einen impliziten Wert erhalten, damit er ein Moo
erstellen kann.
Tags und Links scala