VBA nicht kurzschlussVBA Kurzschluss `und` Alternativen
VBA nicht Kurzschlüsse unterstützen - offenbar, weil es nur bitweise And/Or/Nicht etc Operationen hat. Aus der VBA language specification: "Logische Operatoren sind einfache Datenoperatoren, die bitweise Berechnungen an ihren Operanden durchführen." In diesem Licht betrachtet, macht es Sinn, dass VBA mit true = &H1111
und false = &H0000
entworfen wurde: auf diese Weise logische Aussagen können als bitweise Operationen ausgewertet werden.
Der Mangel an Kurzschluss kann
Leistungsprobleme verursachen: die
ReallyExpensiveFunction()
wird immer ausgeführt, wenn diese Aussage ausgewertet wird, auch wenn es durch das Ergebnis der auf der linken Seite nicht notwendig ist, die BedingungIf IsNecessary() And ReallyExpensiveFunction() Then '... End If
Fehler: wenn MyObj Nichts, dieses bedingte statment wird in einem Laufzeitfehler ist Folge weil VBA noch den Wert von
Property
If Not MyObj Is Nothing And MyObj.Property = 5 Then '... End If
Die Lösung Ich werde versuchen, haben Kurz cirtcuiting Verhalten verwendet, um zu überprüfen zu implementieren verschachtelt ist If
s
If cond1 And cond2 Then
'...
End If
Becomes
If cond1 Then
If cond2 Then
'...
End If
End If
Auf diese Weise der If-Anweisungen das Kurzschlussähnliches Verhalten gibt nicht cond2
wenn cond1
ist False
zu bewerten stört.
Wenn es eine Else-Klausel ist, schafft dies doppelte Codeblocks
If Not MyObj Is Nothing And MyObj.Property = 5 Then
MsgBox "YAY"
Else
MsgBox "BOO"
End If
Werden
If Not MyObj Is Nothing Then
If MyObj.Property = 5 Then
MsgBox "YAY"
Else
MsgBox "BOO" 'Duplicate
End If
Else
MsgBox "BOO" 'Duplicate
End If
Gibt es eine Möglichkeit If
Aussagen zu umschreiben das Kurzschlussverhalten zu erhalten, aber doppelte Code-Vervielfältigung vermeiden?
Vielleicht mit einer anderen Verzweigung Aussage wie Select Case
?
Um Kontext zu der Frage hinzuzufügen, hier ist der spezifische Fall, den ich betrachte. Ich implementiere eine Hash-Tabelle, die Kollisionen behandelt, indem sie sie in einer verknüpften Liste verkettet. Die zugrunde liegende Array-Größe wird als Zweierpotenz erzwungen, und die Hashwerte werden auf die aktuelle Array-Größe verteilt, indem sie auf die entsprechende Länge gekürzt werden.
Angenommen, die Arraylänge ist 16 (binär 10000). Wenn ich einen Schlüssel mit 27 (binär 11011) habe, kann ich ihn in meinem 16-Slot-Array speichern, indem ich nur die Bits innerhalb des Limits dieser Array-Größe belasse.Der Index, in dem dieser Artikel gespeichert wird, ist (hash value) And (length of array - 1)
, was in diesem Fall (binary 11011) And (1111)
ist, was 1011
ist, was 11 ist. Der tatsächliche Hash-Code wird zusammen mit dem Schlüssel im Slot gespeichert.
Beim Suchen eines Elements in der Hash-Tabelle in einer Kette müssen sowohl der Hash als auch der Schlüssel überprüft werden, um festzustellen, ob das richtige Element gefunden wurde. Wenn der Hash jedoch nicht übereinstimmt, besteht kein Grund, den Schlüssel zu überprüfen. Ich hatte gehofft, einige winzige immaterielle Menge an Leistung zu gewinnen, indem sie die Ifs Verschachtelung der Kurzschlussverhalten zu bekommen:
While Not e Is Nothing
If keyhash = e.hash Then
If Key = e.Key Then
e.Value = Value
Exit Property
Else
Set e = e.nextEntry
End If
Else
Set e = e.nextEntry
End If
Wend
Sie sehen die Set...
dupliziert und somit diese Frage.
Vielleicht eine naive Frage, aber können Sie nicht die 'SET' Zeile außerhalb der IFS (und innerhalb der Weile vor der unteren Zeile) bewegen? Sie "SET" nicht nur beim Beenden, sonst setzen Sie. Gute Frage übrigens! – Ioannis
@Ioannis - (Hand auf den Kopf klatschen). Bitte stelle das als Antwort auf. :) – hnk
@loannis Ich kann das nicht tun, es macht WAAAAY zu viel Sinn;) Danke für das Aufzeigen der richtigen Lösung für mein spezifisches Problem, die Änderung an meinem Code jetzt machen ... Ich werde den Rest des lassen Frage allein für die Nachwelt stehen. – Blackhawk