Offensichtlich ist die Fehlerbehandlung im Allgemeinen ein großes Thema, und was die beste Vorgehensweise ist, hängt stark von den Fähigkeiten der Sprache ab, mit der Sie arbeiten und wie die Routine, die Sie programmieren, zu anderen Routinen passt. Daher beschränke ich meine Antwort auf VBA (in Excel) und Routinen vom Typ Bibliothek, die Sie beschreiben.
Ausnahmen vs. Fehlercodes in Bibliotheksroutinen
In diesem Fall würde ich keinen Rückgabecode verwenden. VBA unterstützt eine Form der Ausnahmebehandlung, die zwar nicht so leistungsfähig ist wie das Standardformular in C++/Java/??. NET, aber ziemlich ähnlich ist. Daher gilt allgemein der Rat dieser Sprachen. Sie verwenden Ausnahmen, um aufrufenden Routinen mitzuteilen, dass die aufgerufene Routine ihren Job aus irgendeinem Grund nicht ausführen kann. Sie behandeln Ausnahmen auf der niedrigsten Ebene, auf der Sie etwas Sinnvolles zu diesem Fehler machen können.
Bjarne Stroustrup gibt eine sehr gute Erklärung, warum Ausnahmen in diesem Buch besser als Fehlercodes für diese Art von Situation sind. (Das Buch ist über C++, aber die Prinzipien hinter C++ Ausnahmebehandlung und VBA Fehlerbehandlung sind die gleichen.)
http://www2.research.att.com/~bs/3rd.html
Hier ist ein schöner Ausschnitt ist aus Abschnitt 8.3:
Wenn ein Programm besteht aus separaten Modulen, und vor allem, wenn diese Module aus separat entwickelten Bibliotheken stammen, muss die Fehlerbehandlung in zwei verschiedene Teile getrennt sein: [1] Die Meldung von Fehlerbedingungen, die kann nicht lokal gelöst werden [2] Die Behandlung von Fehlern an anderer Stelle erkannt Der Autor einer Bibliothek kann Laufzeitfehler erkennen, aber im Allgemeinen haben keine Ahnung, was Sie dagegen tun können. Der Benutzer einer Bibliothek kann wissen, wie man mit solche Fehler bewältigen kann, aber kann sie nicht entdecken - oder sie würden im Code des Benutzers gehandhabt werden und nicht verlassen, damit die Bibliothek findet.
Die Abschnitte 14.1 und 14.9 behandeln auch Ausnahmen im Vergleich zu Fehlercodes in einem Bibliothekskontext. (Es gibt eine Kopie des Buches online unter archive.org.)
Es gibt wahrscheinlich viel mehr darüber auf Stackoverflow.Ich habe gerade diese, zum Beispiel:
Exception vs. error-code vs. assert
(. Es kann eine ordnungsgemäße Verwaltung der Ressourcen Gefahren beteiligt, die bereinigt werden müssen, wenn Ausnahmen verwenden, aber sie nicht wirklich hier gelten)
Ausnahmen in VBA
Hier ist, wie eine Ausnahme Erhöhung in VBA sieht (obwohl die VBA Terminologie "eine Fehler Anhebung"):
Function AddArrays(arr1, arr2)
Dim i As Long
Dim result As Variant
' Some error finding code here, e.g.
' - Are input arrays of same size?
' - Are input arrays numeric? (can't add strings, objects...)
' - Etc.
'Assume errorsFound is a variable you populated above...
If errorsFound Then
Call Err.Raise(SOME_BAD_INPUT_CONSTANT) 'See help about the VBA Err object. (SOME_BAD_INPUT_CONSTANT is something you would have defined.)
End If
' If no errors found, do the actual work...
ReDim result(LBound(arr1) To UBound(arr1))
For i = LBound(arr1) To UBound(arr1)
result(i) = arr1(i) + arr2(i)
Next i
AddArrays = result
End Function
Wenn diese Routine den Fehler nicht abfängt, wird VBA anderen Routinen darüber im Call-Stack eine Chance geben (Siehe hierzu: VBA Error "Bubble Up"). So könnte ein Anrufer dies tun:
Was "etwas Sinnvolles" bedeutet, hängt vom Kontext Ihrer Anwendung ab. Im Fall meines oben genannten Anruferbeispiels entscheidet , dass entscheidet, dass einige Fehler behandelt werden sollen, indem ein Fehlerwert zurückgegeben wird, den Excel in eine Arbeitsblattzelle einfügen kann, während andere eine unangenehme Warnung erfordern. (Hier ist der Fall von VBA in Excel eigentlich kein schlechtes spezifisches Beispiel, weil viele Anwendungen zwischen internen und externen Routinen und zwischen Ausnahmen, mit denen Sie rechnen müssen, und Fehlerbedingungen, die Sie nur wissen wollen, unterscheiden aber für die Sie keine Antwort.)
nicht Vergessen Sie Assertions
Weil Sie das Debuggen erwähnt, es ist auch erwähnenswert, die Rolle der Behauptungen. Wenn Sie AddArrays, immer nur aufgerufen werden, indem Routinen erwarten, die tatsächlich haben ihre eigenen Arrays erstellt oder auf andere Weise überprüft sie Arrays verwenden, können Sie dies tun:
Function AddArrays(arr1, arr2)
Dim i As Long
Dim result As Variant
Debug.Assert IsArray(arr1)
Debug.Assert IsArray(arr2)
'rest of code...
End Function
Eine fantastische Diskussion über den Unterschied zwischen Behauptungen und Ausnahmen ist hier :
Debug.Assert vs Exception Throwing
ich habe hier ein Beispiel:
Is assert evil?
Einige VBA Benachrichtigung Impressum Allgemeine Array Behandlungsroutinen
schließlich als VBA-spezifische Note gibt es VBA-Varianten und Arrays sind mit einer Reihe von Gefahren, die vermieden werden müssen, wenn Sie versuchen, allgemeine Bibliothek schreiben Routinen. Arrays können mehr als eine Dimension haben, ihre Elemente können Objekte oder andere Arrays sein, ihre Start- und Endindizes können alles sein usw. Hier ist ein Beispiel (ungetestet und nicht erschöpfend), das einiges davon ausmacht:
'NOTE: This has not been tested and isn't necessarily exhaustive! It's just
'an example!
Function addArrays(arr1, arr2)
'Note use of some other library functions you might have...
'* isVect(v) returns True only if v is an array of one and only one
' dimension
'* lengthOfArr(v) returns the size of an array in the first dimension
'* check(condition, errNum) raises an error with Err.Number = errNum if
' condition is False
'Assert stuff that you assume your caller (which is part of your
'application) has already done - i.e. you assume the caller created
'the inputs, or has already dealt with grossly-malformed inputs
Debug.Assert isVect(arr1)
Debug.Assert isVect(arr2)
Debug.Assert lengthOfArr(arr1) = lengthOfArr(arr2)
Debug.Assert lengthOfArr(arr1) > 0
'Account for VBA array index flexibility hell...
ReDim result(1 To lengthOfArr(arr1)) As Double
Dim indResult As Long
Dim ind1 As Long
ind1 = LBound(arr1)
Dim ind2 As Long
ind2 = LBound(arr2)
Dim v1
Dim v2
For indResult = 1 To lengthOfArr(arr1)
'Note implicit coercion of ranges to values. Note that VBA will raise
'an error if an object with no default property is assigned to a
'variant.
v1 = arr1(ind1)
v2 = arr2(ind2)
'Raise errors if we have any non-numbers. (Don't count a string
'with numeric text as a number).
Call check(IsNumeric(v1) And VarType(v1) <> vbString, xlErrValue)
Call check(IsNumeric(v2) And VarType(v2) <> vbString, xlErrValue)
'Now we don't expect this to raise errors.
result(indResult) = v1 + v2
ind1 = ind1 + 1
ind2 = ind2 + 1
Next indResult
addArrays = result
End Function
Wow. Ich würde das mehr als einmal abstimmen, wenn ich könnte. – RolandTumble
Danke. Ich habe einen Fehler in meinem Hintern über EH in VBA, weil die Leute immer drauf los sind. Und sie vergleichen es fast immer mit Sprachen mit sehr ähnlichen (wenn auch weniger klobigen und zugegebenermaßen nicht mit "On Error Resume Next" bezeichneten) Formen der Ausnahmebehandlung. – jtolle
Dies ist eine kick-ass Antwort! Vielen Dank. –