Warum werden Nullreferenzen gemieden, während das Auslösen von Ausnahmen als in Ordnung angesehen wird?


21

Ich verstehe das konsequente Bashing von Null-Referenzen durch einige Programmiersprachen nicht ganz. Was ist so schlimm an ihnen? Wenn ich Lesezugriff auf eine Datei anfordere, die nicht vorhanden ist, freue ich mich sehr über eine Ausnahme oder einen Nullverweis, und dennoch werden Ausnahmen als gut, aber Nullverweise als schlecht angesehen. Was ist der Grund dafür?



2
Einige Sprachen stürzen besser auf null ab als andere. Für einen "verwalteten Code" wie .Net / Java ist eine Nullreferenz nur eine andere Art von Problem, wohingegen ein anderer systemeigener Code dies möglicherweise nicht ordnungsgemäß handhabt (Sie haben keine bestimmte Sprache erwähnt). Sogar in einer verwalteten Welt möchten Sie manchmal ausfallsicheren Code schreiben (eingebettet ?, Waffen?), Und manchmal möchten Sie so schnell wie möglich laut schimpfen (Unit-Tests). Beide Codetypen könnten in derselben Bibliothek aufgerufen werden - das wäre ein Problem. Im Allgemeinen denke ich, dass Code, der versucht, Computergefühle nicht zu verletzen, eine schlechte Idee ist. Ausfallsicherheit ist sowieso HART.
Job

@Job: Das befürwortet Faulheit. Wenn Sie wissen, wie mit einer Ausnahme umgegangen wird, müssen Sie damit umgehen. Manchmal muss bei dieser Behandlung eine andere Ausnahme ausgelöst werden , aber Sie sollten niemals zulassen, dass eine Nullreferenzausnahme nicht behandelt wird. Je. Das ist der Albtraum eines jeden Wartungsprogrammierers. Es ist die nutzloseste Ausnahme im gesamten Baum. Fragen Sie einfach nach Stack Overflow .
Aaronaught

Oder anders ausgedrückt: Warum nicht einen Code zurückgeben, der Fehlerinformationen darstellt? Dieses Argument wird in den kommenden Jahren wüten.
gbjbaanb

Antworten:


24

NULL-Referenzen werden nicht "gemieden" als Ausnahmen, zumindest von niemandem, den ich jemals gekannt oder gelesen habe. Ich denke, Sie verstehen die konventionelle Weisheit falsch.

Schlecht ist der Versuch, auf eine Nullreferenz zuzugreifen (oder einen Nullzeiger zu dereferenzieren usw.). Das ist schlecht, weil es immer einen Fehler anzeigt; Sie würde nie so etwas wie dies absichtlich tun, und wenn Sie sind es absichtlich tut, dann ist das noch schlimmer, weil es unmöglich zu unterscheiden , das erwartete Verhalten von Buggy Verhalten bewegt.

Es gibt bestimmte Randgruppen da draußen, die das Konzept der Nichtigkeit aus irgendeinem Grund wirklich hassen, aber wie Ed betont , wenn Sie es nicht haben nulloder nildann müssen Sie es einfach durch etwas anderes ersetzen, was zu etwas führen könnte schlimmer als ein Absturz (z. B. Beschädigung von Daten).

Tatsächlich umfassen viele Frameworks beide Konzepte. In .NET ist ein häufiges Muster beispielsweise ein Methodenpaar, dem das Wort Try(z. B. TryGetValue) vorangestellt ist . In diesem TryFall wird die Referenz (normalerweise null) auf den Standardwert gesetzt , und in dem anderen Fall wird eine Ausnahme ausgelöst. Bei beiden Ansätzen ist nichts falsch. beide werden häufig in Umgebungen verwendet, die sie unterstützen.

Es hängt wirklich alles von der Semantik ab. Wenn nulles sich um einen gültigen Rückgabewert handelt, wie im allgemeinen Fall der Suche in einer Sammlung, dann geben Sie zurück null. Wenn es sich jedoch nicht um einen gültigen Rückgabewert handelt, z. B. um das Nachschlagen eines Datensatzes mit einem Primärschlüssel aus Ihrer eigenen Datenbank, ist das Zurückgeben nulleine schlechte Idee, da der Aufrufer dies wahrscheinlich nicht erwartet Ich werde nicht danach suchen.

Es ist wirklich sehr einfach herauszufinden, welche Semantik verwendet werden soll: Ist es sinnvoll, wenn das Ergebnis einer Funktion undefiniert ist? In diesem Fall können Sie eine Nullreferenz zurückgeben. Wenn nicht, eine Ausnahme auslösen.


5
Tatsächlich gibt es Sprachen, die weder null noch null haben und "nicht durch etwas anderes ersetzen müssen". Nullable Verweise implizieren, dass möglicherweise etwas vorhanden ist oder nicht. Wenn Sie den Benutzer lediglich dazu auffordern, explizit zu prüfen, ob etwas vorhanden ist, haben Sie das Problem gelöst. Siehe haskell für ein reales Beispiel.
Johanna Larsson

3
@ErikKronberg, ja, der "Milliarden-Dollar-Fehler" und all dieser Unsinn, die Parade der Leute, die dies ausloten und behaupten, es sei frisch und faszinierend, hört nie auf, deshalb wurde der vorherige Kommentarthread gelöscht. Diese revolutionären Ersetzungen, die Menschen immer wieder vorbringen, sind immer eine Variante des Null-Objekts, der Null-Option oder des Null-Vertrags, die den zugrunde liegenden logischen Fehler nicht auf magische Weise beseitigen, sondern lediglich aufschieben oder fördern. Wie auch immer, dies ist offensichtlich eine Frage zu Programmiersprachen , die tun haben null, also wirklich, Haskell hier ziemlich irrelevant ist.
Aaronaught

1
Argumentieren Sie ernsthaft, dass es genauso gut ist, keinen Test für null zu verlangen, wie ihn zu verlangen?
Johanna Larsson

3
@ErikKronberg: Ja, ich argumentiere "ernsthaft", dass das Testen auf Null nicht besonders verschieden ist von (a) dem Entwerfen jeder Ebene einer Anwendung um das Verhalten eines Null-Objekts, (b) dem Musterspiel Optionen die ganze Zeit oder (c) dem Angerufenen nicht erlauben, "Ich weiß nicht" zu sagen und eine Ausnahme oder einen Absturz zu erzwingen. Es gibt einen Grund, warum nulles so lange so gut ausgehalten hat, und die Mehrheit der Leute, die etwas anderes sagen, scheinen Akademiker mit wenig Erfahrung darin zu sein, echte Apps mit Einschränkungen wie unvollständigen Anforderungen oder etwaiger Konsistenz zu entwerfen.
Aaronaught

3
@Aaronaught: Manchmal wünschte ich, es gäbe einen Downvote-Button für Kommentare. Es gibt keinen Grund, so zu schimpfen.
Michael Shaw

11

Der große Unterschied besteht darin, dass, wenn Sie den Code für die Behandlung von NULL-Werten weglassen, der Code möglicherweise zu einem späteren Zeitpunkt mit einer nicht zusammenhängenden Fehlermeldung weiter abstürzt, wobei die Ausnahme wie bei Ausnahmen beim ersten Fehler (Öffnen) ausgelöst wird eine Datei zum Lesen in Ihrem Beispiel).


4
Wenn Sie nicht mit NULL umgehen, besteht die Gefahr, dass Sie die Schnittstelle zwischen Ihrem Code und dem zurückgegebenen Code nicht kennen. Entwickler, die diesen Fehler machen würden, würden andere in einer Sprache machen, die keine NULL-Werte macht.
Blrfl

@Blrfl, im Idealfall sind die Methoden ziemlich kurz und daher ist es einfach, genau herauszufinden, wo das Problem auftritt. Ein guter Debugger kann normalerweise eine Nullreferenzausnahme gut finden, selbst wenn der Code lang ist. Was soll ich tun, wenn ich versuche, eine kritische Einstellung aus einer Registrierung zu lesen, die nicht vorhanden ist? Meine Registrierung ist durcheinander und ich bin besser darin, den Benutzer zu ärgern, als einen Knoten stillschweigend neu zu erstellen und auf den Standardwert zu setzen. Was ist, wenn ein Virus dies getan hat? Wenn ich also eine Null bekomme, sollte ich eine spezielle Ausnahme auslösen oder sie einfach zerreißen lassen? Was ist bei kurzen Methoden der große Unterschied?
Job

@Job: Was ist, wenn Sie keinen Debugger haben? Sie wissen, dass Ihre Anwendung zu 99,99% in einer Release-Umgebung ausgeführt wird? In diesem Fall wünschen Sie sich, Sie hätten eine sinnvollere Ausnahme verwendet. Möglicherweise muss Ihre App immer noch ausfallen und den Benutzer ärgern, es werden jedoch Debug-Informationen ausgegeben, mit denen Sie das Problem umgehend aufspüren und den Ärger auf ein Minimum beschränken können.
Aaronaught

@Birfl, manchmal möchte ich nicht den Fall behandeln, in dem eine Null natürlich zurückgegeben werden würde. Angenommen, ich habe einen Container, der Schlüssel zu Werten zuordnet. Wenn meine Logik garantiert, dass ich niemals versuche, Werte zu lesen, die ich nicht zuerst gespeichert habe, sollte ich niemals null zurückerhalten. In diesem Fall hätte ich lieber eine Ausnahme, die so viele Informationen wie möglich liefert, um anzuzeigen, was schief gelaufen ist, und dann eine Null zurückgibt, um auf mysteriöse Weise an einer anderen Stelle im Programm zu versagen.
Winston Ewert

Anders ausgedrückt, mit Ausnahmen muss ich den ungewöhnlichen Fall explizit behandeln, sonst stirbt mein Programm sofort ab. Wenn der Code mit Nullverweisen den ungewöhnlichen Fall nicht explizit behandelt, wird versucht, weiterzuhinken. Ich denke, es ist besser, den Fail-Now-Fall anzunehmen.
Winston Ewert

8

Da Nullwerte kein notwendiger Bestandteil einer Programmiersprache sind und eine konsistente Fehlerquelle darstellen. Wie Sie sagen, kann das Öffnen einer Datei zu einem Fehler führen, der entweder als Nullrückgabewert oder über eine Ausnahme zurückgemeldet werden kann. Wenn Nullwerte nicht zulässig sind, gibt es eine einheitliche Möglichkeit, Fehler zu kommunizieren.

Dies ist auch nicht das häufigste Problem bei Nullen. Die meisten Leute denken daran, nach dem Aufruf einer Funktion, die sie möglicherweise zurückgibt, auf null zu prüfen. Das Problem taucht viel häufiger in Ihrem eigenen Design auf, indem Sie zulassen, dass Variablen an verschiedenen Stellen der Programmausführung null sind. Sie können Ihren Code so gestalten, dass NULL-Werte niemals zulässig sind. Wenn NULL jedoch auf Sprachebene nicht zulässig wäre, wäre dies nicht erforderlich.

In der Praxis benötigen Sie jedoch noch eine Möglichkeit, um anzugeben, ob eine Variable initialisiert ist oder nicht. Sie haben dann eine Art Fehler, bei dem Ihr Programm nicht abstürzt, sondern weiterhin einen möglicherweise ungültigen Standardwert verwendet. Ich weiß ehrlich gesagt nicht, was besser ist. Für mein Geld stürze ich gerne früh und oft.


Stellen Sie sich eine nicht initialisierte Unterklasse mit einer identifizierenden Zeichenfolge vor, und alle ihre Methoden lösen Ausnahmen aus. Wenn einer von diesen jemals auftaucht, wissen Sie, was passiert ist. Auf eingebetteten Systemen mit begrenztem Speicher kann die Produktionsversion der Uninitialized Factory nur null zurückgeben.
Jim Balter

3
@ Jim Balter: Ich glaube, ich bin verwirrt darüber, wie es in der Praxis wirklich helfen würde. In jedem nicht trivialen Programm müssen Sie sich irgendwann mit Werten befassen, die möglicherweise nicht initialisiert werden. Es muss also eine Möglichkeit geben, einen Standardwert zu kennzeichnen. Daher müssen Sie dies immer noch überprüfen, bevor Sie fortfahren. Anstelle eines möglichen Absturzes arbeiten Sie jetzt möglicherweise mit ungültigen Daten.
Ed S.

1
Sie wissen auch, was passiert ist, wenn Sie nullals Rückgabewert erhalten: Die angeforderten Informationen sind nicht vorhanden. Es gibt keinen Unterschied. In beiden Fällen muss der Aufrufer den Rückgabewert validieren, wenn er diese Informationen tatsächlich für einen bestimmten Zweck verwenden muss. Ob es sich um die Validierung eines nullObjekts, eines Nullobjekts oder einer Monade handelt, spielt praktisch keine Rolle.
Aaronaught

1
@ Jim Balter: Richtig, ich sehe immer noch keinen praktischen Unterschied, und ich sehe nicht, wie es Menschen, die echte Programme außerhalb der akademischen Welt schreiben, das Leben erleichtert. Das heißt nicht, dass es keine Vorteile gibt, nur, dass sie mir nicht offensichtlich erscheinen.
Ed S.

1
Ich habe den praktischen Unterschied zu einer nicht initialisierten Klasse zweimal erklärt - sie identifiziert den Ursprung des Null-Elements - und ermöglicht es, den Fehler zu lokalisieren, wenn eine Dereferenzierung von Null auftritt. Die Sprachen, die auf Null-weniger-Paradigmen basieren, umgehen das Problem von Anfang an - sie bieten alternative Möglichkeiten zum Programmieren. Dadurch werden nicht initialisierte Variablen vermieden. Das scheint schwer zu begreifen, wenn Sie nicht mit ihnen vertraut sind. Strukturierte Programmierung, die auch eine große Klasse von Fehlern vermeidet, galt einst auch als "akademisch".
Jim Balter

5

Tony Hoare, der in erster Linie die Idee einer Nullreferenz erfunden hat, nennt sie einen Fehler von einer Million Dollar .

Das Problem betrifft nicht Null-Referenzen per se, sondern das Fehlen einer ordnungsgemäßen Typprüfung in den meisten (sonst) typsicheren Sprachen.

Diese mangelnde Unterstützung durch die Sprache bedeutet, dass Fehler "Null-Fehler" möglicherweise lange Zeit im Programm lauern, bevor sie erkannt werden. Das ist natürlich die Natur von Fehlern, aber es ist bekannt, dass die "Null-Fehler" vermeidbar sind.

Dieses Problem tritt insbesondere in C oder C ++ (zum Beispiel) auf, weil es einen "harten" Fehler verursacht (sofortiger Absturz des Programms ohne elegante Wiederherstellung).

In anderen Sprachen stellt sich immer die Frage, wie man damit umgeht.

In Java oder C # erhalten Sie eine Ausnahme, wenn Sie versuchen, eine Methode für eine Nullreferenz aufzurufen, und dies ist möglicherweise in Ordnung. Und deshalb sind die meisten Java- oder C # -Programmierer daran gewöhnt und verstehen nicht, warum man es anders machen möchte (und lachen über C ++).

In Haskell müssen Sie explizit eine Aktion für den Null-Fall bereitstellen, und daher beklagen sich die Haskell-Programmierer bei ihren Kollegen, weil sie es richtig verstanden haben (richtig?).

Es ist wirklich die alte Debatte um Fehlercode / Ausnahmen, aber diesmal mit einem Sentinel-Wert anstelle von Fehlercode.

Wie immer hängt es von der Situation und der gesuchten Semantik ab, was am besten geeignet ist.


Genau. nullist wirklich böse, weil es das Typensystem untergräbt . (Zugegeben, die Alternative hat einen Nachteil in ihrer Ausführlichkeit, zumindest in einigen Sprachen.)
Mechanische Schnecke

2

Sie können keine für Menschen lesbare Fehlermeldung an einen Nullzeiger anhängen.

(Sie können jedoch eine Fehlermeldung in einer Protokolldatei hinterlassen.)

In einigen Sprachen / Umgebungen , die Zeigerarithmetik erlauben, wenn eine der Zeiger Argument null ist , und es wird in die Berechnung erlaubt, wäre das Ergebnis ein sein ungültig , nicht-Null - Zeiger. (*) Mehr Kraft für Sie.

(*) Dies passiert häufig bei der COM- Programmierung. Wenn Sie versuchen, eine Schnittstellenmethode aufzurufen, der Schnittstellenzeiger jedoch Null ist, wird eine ungültige Adresse aufgerufen, die fast, aber nicht ganz genau Null ist.


2

Das Zurückgeben von NULL (oder einer numerischen Null oder eines booleschen Fehlers), um einen Fehler anzuzeigen, ist technisch und konzeptionell falsch.

Technisch gesehen belasten Sie den Programmierer mit der sofortigen Überprüfung des Rückgabewerts, genau an dem Punkt, an dem er zurückgegeben wird. Wenn Sie zwanzig Dateien hintereinander öffnen und die Fehlersignalisierung durch die Rückgabe von NULL erfolgt, muss der konsumierende Code jede gelesene Datei einzeln prüfen und aus Schleifen und ähnlichen Konstrukten ausbrechen. Dies ist ein perfektes Rezept für überfüllten Code. Wenn Sie sich jedoch dafür entscheiden, den Fehler durch Auslösen einer Ausnahme zu signalisieren, kann der konsumierende Code entscheiden, die Ausnahme sofort zu behandeln, oder sie auch über Funktionsaufrufe hinweg in beliebig viele Ebenen sprudeln lassen. Dies sorgt für viel saubereren Code.

Wenn Sie eine Datei öffnen und ein Fehler auftritt, ist die Rückgabe eines Werts (sogar NULL) konzeptionell falsch. Sie müssen nichts zurückgeben, da Ihre Operation nicht abgeschlossen wurde. Die Rückgabe von NULL ist die konzeptionelle Entsprechung von "Ich habe die Datei erfolgreich gelesen und hier ist, was sie enthält - nichts". Wenn Sie dies ausdrücken möchten (d. H. Wenn NULL als tatsächliches Ergebnis für die betreffende Operation sinnvoll ist), geben Sie auf jeden Fall NULL zurück. Wenn Sie jedoch einen Fehler signalisieren möchten, verwenden Sie Ausnahmen.

In der Vergangenheit wurden Fehler auf diese Weise gemeldet, da in Programmiersprachen wie C keine Ausnahmebehandlung integriert ist und die empfohlene Methode (mit langen Sprüngen) etwas haarig und kontraintuitiv ist.

Das Problem hat auch eine Wartungsseite: Mit Ausnahmen müssen Sie zusätzlichen Code schreiben, um den Fehler zu beheben. Wenn Sie dies nicht tun, wird das Programm früh und schwer scheitern (was gut ist). Wenn Sie NULL zurückgeben, um Fehler zu signalisieren, ignoriert das Programm standardmäßig den Fehler und setzt den Vorgang fort, bis andere Probleme auftreten - beschädigte Daten, Segfaults, NullReferenceExceptions, abhängig von der Sprache. Um den Fehler früh und laut zu signalisieren, müssen Sie zusätzlichen Code schreiben und raten: Dies ist der Teil, der ausgelassen wird, wenn Sie sich in einer engen Frist befinden.


1

Wie bereits erwähnt, konvertieren viele Sprachen eine Dereferenzierung eines Nullzeigers nicht in eine abfangbare Ausnahme. Das ist ein relativ moderner Trick. Als das Nullzeigerproblem zum ersten Mal erkannt wurde, waren noch nicht einmal Ausnahmen erfunden worden.

Wenn Sie Nullzeiger als gültigen Fall zulassen, ist dies ein Sonderfall. Sie benötigen eine spezielle Behandlungslogik, oft an vielen verschiedenen Stellen. Das ist zusätzliche Komplexität.

Unabhängig davon, ob es sich um potenzielle Nullzeiger handelt oder nicht, müssen Sie diese Ausnahmefälle auf eine andere Weise behandeln , wenn Sie keine Ausnahmewürfe zur Behandlung von Ausnahmefällen verwenden. In der Regel muss jeder Funktionsaufruf auf diese Ausnahmefälle überprüft werden, um zu verhindern, dass der Funktionsaufruf unangemessen aufgerufen wird, oder um den Fehlerfall zu erkennen, wenn die Funktion beendet wird. Das ist zusätzliche Komplexität, die durch Ausnahmen vermieden werden kann.

Mehr Komplexität bedeutet normalerweise mehr Fehler.

Alternativen zur Verwendung von Nullzeigern in Datenstrukturen (z. B. zum Markieren des Anfangs / Endes einer verknüpften Liste) umfassen die Verwendung von Sentinel-Elementen. Diese können die gleiche Funktionalität mit einer viel geringeren Komplexität bieten. Es gibt jedoch auch andere Möglichkeiten, die Komplexität zu verwalten. Eine Möglichkeit besteht darin, den potenziellen Nullzeiger in eine Smart Pointer-Klasse einzufügen, sodass die Nullprüfungen nur an einer Stelle erforderlich sind.

Was ist mit dem Nullzeiger zu tun, wenn er erkannt wird? Wenn Sie die Ausnahmebehandlung nicht einbauen können, können Sie immer eine Ausnahme auslösen und diese Sonderfallbehandlung effektiv an den Aufrufer delegieren. Und genau das tun einige Sprachen standardmäßig, wenn Sie einen Nullzeiger dereferenzieren.


1

Spezifisch für C ++, aber es null Referenzen gibt es gemieden , weil null Semantik in C ++ mit Zeigertypen zugeordnet sind. Es ist durchaus sinnvoll, dass eine Funktion zum Öffnen von Dateien fehlschlägt und einen Nullzeiger zurückgibt. in der Tat macht die fopen()Funktion genau das.


Wenn Sie sich in C ++ mit einer Nullreferenz befinden, liegt dies in der Tat daran, dass Ihr Programm bereits fehlerhaft ist .
Kaz Dragon

1

Das hängt von der Sprache ab.

Beispielsweise können Sie mit Objective-C problemlos eine Nachricht an ein Null-Objekt (nil) senden. Ein Aufruf von nil gibt ebenfalls nil zurück und wird als Sprachfunktion betrachtet.

Mir persönlich gefällt es, da Sie sich auf dieses Verhalten verlassen und all diese verschachtelten if(obj == null)Konstrukte vermeiden können .

Zum Beispiel:

if (myObject != nil && [myObject doSomething])
{
    ...
}

Kann gekürzt werden auf:

if ([myObject doSomething])
{
    ...
}

Kurz gesagt, es macht Ihren Code besser lesbar.


0

Es ist mir egal, ob Sie eine Null zurückgeben oder eine Ausnahme auslösen, solange Sie dies dokumentieren.


Und nennen Sie es auch: GetAddressMaybeoder GetSpouseNameOrNull.
rwong

-1

Eine Nullreferenz tritt normalerweise auf, weil etwas in der Programmlogik übersehen wurde, dh: Sie sind zu einer Codezeile gekommen, ohne die erforderliche Einrichtung für diesen Codeblock durchzugehen.

Wenn Sie dagegen eine Ausnahme für etwas auslösen, bedeutet dies, dass Sie erkannt haben, dass im normalen Betrieb des Programms eine bestimmte Situation eintreten kann, und dass diese behandelt wird.


2
Eine Nullreferenz kann aus einer Vielzahl von Gründen "vorkommen", von denen nur sehr wenige etwas betreffen, das übersehen wird. Vielleicht bekommen Sie es auch mit einer Null - Referenz verwechselt Ausnahme .
Aaronaught

-1

NULL-Referenzen sind oft sehr nützlich: Beispielsweise kann ein Element in einer verknüpften Liste einen Nachfolger oder keinen Nachfolger haben. Die Verwendung nullfür "keinen Nachfolger" ist völlig selbstverständlich. Oder eine Person kann einen Ehepartner haben oder nicht - die Verwendung nullvon "Person hat keinen Ehepartner" ist vollkommen natürlich, viel natürlicher als die Verwendung eines bestimmten "hat keinen Ehepartner" -Sonderwerts, auf den sich das Person.SpouseMitglied beziehen könnte.

Aber: Viele Werte sind nicht optional. In einem typischen OOP-Programm kann nicht mehr als die Hälfte der Referenzen nullnach der Initialisierung vorhanden sein, da sonst das Programm fehlschlägt. Andernfalls müsste der Code mit if (x != null)Schecks durchsetzt werden. Warum sollte also jeder Verweis standardmäßig nullbar sein? Es sollte wirklich umgekehrt sein: Variablen sollten standardmäßig nicht nullfähig sein, und Sie sollten explizit "oh, und dieser Wert kann nullauch" sagen .


Gibt es etwas aus dieser Diskussion, das Sie Ihrer Antwort hinzufügen möchten? Dieser Kommentarthread wurde ein wenig hitzig und wir möchten das aufräumen. Jede längere Diskussion sollte zum Chatten genommen werden .

Inmitten all dieses Streites könnte es einen oder zwei Punkte von tatsächlichem Interesse gegeben haben. Leider habe ich Marks Kommentar erst gesehen, als ich die ausführliche Diskussion zurückgeschnitten habe. Weisen Sie die Moderatoren in Zukunft auf Ihre Antwort hin, wenn Sie die Kommentare so lange aufbewahren möchten, bis Sie Zeit haben, sie zu überprüfen und Ihre Antwort entsprechend zu bearbeiten.
Josh K

-1

Ihre Frage ist verwirrend formuliert. Meinen Sie eine Nullreferenz Ausnahme (die durch einen Versuch tatsächlich dazu gebracht wird, , deReferenz null)? Der eindeutige Grund, diese Art von Ausnahme nicht zu wollen, besteht darin, dass Sie keine Informationen darüber erhalten, was schief gelaufen ist oder sogar wann - der Wert hätte zu jedem Zeitpunkt im Programm auf null gesetzt werden können. Sie schreiben: "Wenn ich Lesezugriff auf eine Datei anfordere, die nicht vorhanden ist, freue ich mich über eine Ausnahme oder einen Nullverweis." Sie sollten sich jedoch nicht über etwas freuen, das keinen Hinweis auf die Ursache enthält . Nirgendwo in der Zeichenfolge "wurde versucht, null zu dereferenzieren" wird das Lesen oder nicht vorhandene Dateien erwähnt. Vielleicht meinen Sie damit, dass Sie sich über den Nullwert als Rückgabewert eines Leseaufrufs sehr freuen würden - das ist eine ganz andere Sache, aber es gibt Ihnen immer noch keine Informationen darüber, warum der Lesevorgang fehlgeschlagen ist. es'


Nein, ich meine keine Null-Referenz-Ausnahme. In allen mir bekannten Sprachen sind nicht initialisierte, aber deklarierte Variablen eine Form von Null.
Davidk01

Ihre Frage betraf jedoch nicht nicht initialisierte Variablen. Und es gibt Sprachen, die nicht null für nicht initialisierte Variablen verwenden, sondern Wrapper-Objekte verwenden, die optional einen Wert enthalten können - beispielsweise Scala und Haskell.
Jim Balter

1
"... verwenden Sie stattdessen Wrapper-Objekte, die optional einen Wert enthalten können ." Was eindeutig nichts mit einem nullbaren Typ zu tun hat .
Aaronaught

1
In haskell gibt es keine nicht initialisierte Variable. Sie könnten möglicherweise ein IORef deklarieren und es mit None als Anfangswert festlegen, aber das ist so ziemlich das Analoge, wenn Sie eine Variable in einer anderen Sprache deklarieren und uninitialisieren, was die gleichen Probleme mit sich bringt. Bei der Arbeit im rein funktionalen Kern außerhalb der E / A-Monade greifen Haskell-Programmierer nicht auf Referenztypen zurück, sodass es kein Nullreferenzproblem gibt.
Davidk01

1
Wenn Sie einen außergewöhnlichen "Fehlenden" Wert haben, ist dies genau das Gleiche wie ein außergewöhnlicher "Null" Wert - wenn Sie die gleichen Werkzeuge zur Verfügung haben, um damit umzugehen. Das ist ein signifikantes "Wenn". Sie benötigen zusätzliche Komplexität, um diesen Fall in beiden Fällen zu behandeln. In Haskell bieten der Mustervergleich und das Typensystem eine Möglichkeit, diese Komplexität zu verwalten. Es gibt jedoch andere Tools zum Verwalten der Komplexität in anderen Sprachen. Ausnahmen sind ein solches Werkzeug.
Steve314
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.