Frage

Die Go Sprache Schöpfer schreiben :

  

Go bietet keine Aussagen. Sie sind unbestreitbar bequem, aber unsere Erfahrung ist, dass Programmierer sie als Krücke über die richtige Fehlerbehandlung und Berichterstattung zu vermeiden denken. Die richtige Fehlerbehandlung bedeutet, dass die Server auch weiterhin den Betrieb nach nicht-fatalen Fehlern statt Krachen. Die richtige Fehlerberichterstattung bedeutet, dass Fehler sind direkt und auf den Punkt, von dem Programmierer das Speichern einer großen Crash Spur zu interpretieren. Präzise Fehler sind besonders wichtig, wenn der Programmierer der Fehler zu sehen, nicht vertraut mit dem Code.

Was ist Ihre Meinung dazu?

War es hilfreich?

Lösung

Nein, es ist nichts falsch mit assert so lange, wie Sie es verwenden, wie beabsichtigt.

Das heißt, es soll für den Fang von Fällen sein, dass während des Debuggen „passieren kann, nicht“ im Gegensatz zu normaler Fehlerbehandlung.

  • Assert: Ein Fehler in der Logik des Programms selbst
  • .
  • Fehlerbehandlung. Eine fehlerhafte Eingabe oder Systemzustand nicht aufgrund eines Fehlers im Programm

Andere Tipps

Nein, weder noch goto assert sind böse. Aber beide können missbraucht werden.

Assert ist für Plausibilitätsprüfungen. Dinge, die das Programm töten sollten, wenn sie nicht korrekt sind. Nicht für die Validierung oder als Ersatz für die Fehlerbehandlung.

Nach dieser Logik, Haltepunkte sind zu böse.

ASSERTS sollte als Testhilfe verwendet werden, und nichts anderes. "Evil" ist, wenn man mit ihnen versuchen statt der Fehlerbehandlung.

Asserts sind für Sie da, den Programmierer, erkennen und beheben Probleme zu helfen, die nicht vorhanden sein müssen, und sicherstellen, dass Ihre Annahmen treu bleiben.

Sie haben nichts mit der Fehlerbehandlung zu tun, aber leider einige Programmierer missbrauchen sie als solche, und dann erklären sie „böse“.

Ich mag assert viel verwenden. Ich finde es sehr nützlich, wenn ich den Aufbau von Anwendungen zum ersten Mal (vielleicht für eine neue Domäne). Statt Überprüfung sehr extravagant Fehler machen (die ich vorzeitige Optimierung berücksichtigen würde) I-Code schnell und ich füge hinzu viel behauptet. Nachdem ich mehr darüber wissen, wie die Dinge funktionieren kann ich eine Rewrite und einige des entfernen behauptet und sich für eine bessere Fehlerbehandlung ändern.

Aufgrund der behauptet ich viel weniger Zeit Codierung / Debug-Programme ausgeben.

Ich habe auch bemerkt, dass die mir helfen, denken viele Dinge behauptet, dass meine Programme brechen könnte.

Sie sollten zum Nachweis von Fehlern im Programm verwendet werden. Nicht schlecht Benutzereingabe.

Wenn es richtig verwendet, sie sind nicht Übel.

Als zusätzliche Informationen finden Sie bietet eine integrierte Funktion panic. Dies kann anstelle von assert verwendet werden. Z.

if x < 0 {
    panic("x is less than 0");
}

panic wird den Stack-Trace drucken, so in gewisser Weise den Zweck assert hat.

Das kommt viel, und ich denke, ein Problem, das verwirrende Verteidigung Behauptungen macht, ist, dass sie oft auf einer Überprüfung der Argumente basieren. So betrachten Sie dieses anderes Beispiel, wenn Sie könnten eine Assertion verwenden:

build-sorted-list-from-user-input(input)

    throw-exception-if-bad-input(input)

    ...

    //build list using algorithm that you expect to give a sorted list

    ...

    assert(is-sorted(list))

end

Sie verwenden, um eine Ausnahme für die Eingabe, weil Sie Sie erwarten, manchmal schlecht Eingang bekommen. Sie behaupten, dass die Liste sortiert ist Sie einen Fehler in Ihrem Algorithmus finden helfen, die definitions Sie nicht erwarten. Die Behauptung ist in der Debug-Build nur, so dass, obwohl die Prüfung teuer ist, es Ihnen nichts ausmacht es auf jedem einzelnen Aufruf der Routine zu tun.

Sie noch haben Unit-Test Ihre Produktion Code, aber das ist eine andere und ergänzende Art und Weise zu machen, dass der Code korrekt ist. Unit-Tests stellen sicher, dass Ihre Routine macht seinen Interface, während Behauptungen eine feinere Art und Weise sind, um sicherzustellen, dass Ihre Implementierung genau das tut, was Sie es erwarten.

Assertions sind nicht böse, aber sie können leicht missbraucht werden. Ich stimmen der Aussage zu, dass „Behauptungen oft als Krücke benutzt denken über die richtige Fehlerbehandlung zu vermeiden und Berichterstattung“. Ich habe dies sehr oft gesehen.

Ich persönlich mag Behauptungen verwenden, da sie Annahmen dokumentieren, dass ich meinen Code gemacht haben könnte beim Schreiben. Wenn diese Annahmen gebrochen werden, während Sie den Code beibehalten wird, kann das Problem während der Prüfung festgestellt werden. Ich habe jedoch den Punkt Strippen jeder von meinem Code behaupten, wenn eine Produktion aufbauen zu tun (das heißt, mit #ifdefs). Durch Strippen der Behauptungen in der Produktion Build aus, beseitige ich das Risiko von jemandem sich als Krücke zu mißbrauchen.

Es gibt auch ein anderes Problem mit Behauptungen. Assertions sind nur zur Laufzeit überprüft. Aber es ist oft der Fall, dass der Scheck Sie möchten, könnte ausführen zur Compile-Zeit durchgeführt wurde. Es ist bevorzugt, ein Problem bei der Kompilierung zu erkennen. Für C ++ Programmierer, Boost bietet BOOST_STATIC_ASSERT, die Sie dies tun können. Für C-Programmierer, dieser Artikel ( Link-Text ) beschreibt eine Technik, die verwendet werden kann, um durchzuführen bei der Kompilierung Behauptungen.

Zusammenfassend ich die Faustregel, folge: Verwenden Behauptungen nicht in einer Produktions bauen und, wenn möglich, nur Aussagen für Dinge verwenden, die (dh nicht zur Compile-Zeit überprüft werden, muss zur Laufzeit überprüft werden ).

Ich habe zugeben zu haben behauptet, obwohl sie nicht die richtige Fehlerberichterstattung unter Berücksichtigung. Sie jedoch, dass nicht wegnehmen, dass sie sehr nützlich sind, wenn sie richtig verwendet wird.

Sie sind besonders nützlich für, wenn Sie die „Crash Früh“ -Prinzip folgen. Zum Beispiel: Angenommen, Sie einen Referenz Zählmechanismus sind implementiert. An bestimmten Stellen in Ihrem Code Sie wissen, dass die refcount sollte null oder eins sein. Und auch annehmen, dass, wenn die refcount falsch ist das Programm nicht sofort abstürzen, aber während der nächsten Nachrichtenschleife an welcher Stelle es schwierig sein wird, um herauszufinden, warum Dinge schief gelaufen ist. Ein assert wäre hilfreich gewesen, den Fehler näher an seinen Ursprung bei der Erkennung.

Ich ziehe es vermeiden Code, verschiedene Dinge im Debug-und Release der Fall ist.

Breaking im Debugger auf einem Zustand und mit alle Datei / Zeile info ist nützlich, aber auch der genaue Ausdruck und der genaue Wert.

eine Assertion zu haben, das „die Bedingung nur in Debug bewerten“ wäre möglicherweise eine Performance-Optimierung sein, und als solche nützlich nur in 0,0001% der Programme - wo die Leute wissen, was sie tun. In allen anderen Fällen ist dies schädlich, da der Ausdruck tatsächlich Programms Zustand ändern kann:

assert(2 == ShroedingersCat.GetNumEars()); würde das Programm verschiedene Dinge tun, in Debug und Release.

Wir haben eine Reihe von assert Makros entwickelt, die eine Ausnahme auslösen würde, und tun es in beiden Debug-und Release-Version. Zum Beispiel THROW_UNLESS_EQ(a, 20); würde eine Ausnahme mit dem, was () Nachricht sowohl Datei, Leitung und der Ist-Wert a, und so weiter werfen. Nur würde ein Makro die Kraft dafür. Der Debugger kann konfiguriert sein, den spezifischen Ausnahmetypen auf ‚werfen‘ zu brechen.

ich behauptet intensiv nicht mögen. Ich würde nicht so weit zu sagen sie sind böse gehen aber.

Im Grunde eine Assertion wird die gleiche Sache wie eine ungeprüfte Ausnahme tun würde, ist die einzige Ausnahme, dass die assert (normalerweise) nicht für das Endprodukt gehalten werden.

Wenn Sie ein Sicherheitsnetz für sich selbst bauen, während das Debuggen und das System baut, warum Sie dieses Sicherheitsnetz für Ihre Kunden verweigern würde, oder Ihre Unterstützung Helpdesk oder jemand, der die Software zu verwenden, die Sie zur Zeit bauen. Verwenden Sie Ausnahmen ausschließlich für beide behauptet und Ausnahmesituationen. eine entsprechende Ausnahme Hierarchie sind Sie in der Lage sein, sehr schnell von dem anderen zu unterscheiden. Außer dieser Zeit bleibt die Assertion an Ort und Stelle und kann wertvolle Informationen im Falle des Scheiterns, die sonst verloren gehen würden.

So verstehe ich voll und ganz die Macher von Go durch behauptet komplett zu entfernen und zwingt Programmierer Ausnahmen zu verwenden, um die Situation zu handhaben. Es gibt eine einfache Erklärung dafür, Ausnahme ist nur ein besserer Mechanismus für den Job, warum mit dem archaischen Stick behauptet?

Kurze Antwort: Nein, ich glaube Behauptungen nützlich sein können,

Ich habe vor kurzem begonnen, das Hinzufügen einige meinen Code behaupten, und das ist, wie ich habe es getan:

Ich teile geistig meinen Code in Grenzcode und internen Code. Boundary-Code ist Code, der Benutzereingabe behandelt, liest Dateien und erhält Daten aus dem Netzwerk. In diesem Code anfordern I-Eingang in einer Schleife, die nur beendet, wenn der Eingang (im Fall von interaktiver Benutzereingabe) gültig ist, oder Ausnahmen im Fall von nicht behebbaren Datei / Netzwerk korrupter Daten werfen.

Interner Code ist alles andere. Zum Beispiel kann eine Funktion, die eine Variable in meiner Klasse setzt möglicherweise als

definiert werden
void Class::f (int value) {
    assert (value < end);
    member = value;
}

und eine Funktion, die Eingabe von einem Netzwerk wird möglicherweise als solche gelesen:

void Class::g (InMessage & msg) {
    int const value = msg.read_int();
    if (value >= end)
        throw InvalidServerData();
    f (value);
}

Das gibt mir zwei Schichten überprüft. Alles, wo die Daten zur Laufzeit bestimmt wird, bekommt immer eine Ausnahme oder sofortige Fehlerbehandlung. Jedoch, dass zusätzliche Kontrolle in Class::f mit der assert Aussage bedeutet, dass, wenn einige interne Code jemals Class::f nennt, habe ich noch eine Plausibilitätsprüfung haben. Mein interner Code könnte kein gültiges Argument übergeben (weil ich value von einer komplexen Reihe von Funktionen berechnet habe), so wie ich sich in der Einstellungsfunktion zu dokumentieren die Behauptung aufweisen, unabhängig davon, wer die Funktion aufruft, value nicht größer sein muss als oder gleich end.

Dies scheint in passen, was ich an einigen Stellen gerade lese, dass Behauptungen unmöglich sein sollten in einem gut funktionierenden Programm zu verletzen, während Ausnahmen für außergewöhnliche und fehlerhafte Fälle sein sollen, die noch möglich sind. Denn in der Theorie ich alle Eingaben bin Validierung, sollte es nicht möglich sein, für meine Behauptung ausgelöst werden. Wenn ja, mein Programm ist falsch.

assert sehr nützlich ist, und können Sie eine Menge Rückzieher sparen, wenn unerwartete Fehler durch Anhalten des Programms bei den ersten Anzeichen von Schwierigkeiten auftreten.

Auf der anderen Seite ist es sehr einfach assert zu missbrauchen.

int quotient(int a, int b){
    assert(b != 0);
    return a / b;
}

Die richtige, korrekte Version wäre so etwas wie:

bool quotient(int a, int b, int &result){
    if(b == 0)
        return false;

    result = a / b;
    return true;
}

So ... auf lange Sicht ... in das große Bild ... Ich muss assert zustimmen missbraucht werden kann. Ich mache es die ganze Zeit.

assert für die Fehlerbehandlung missbraucht wird, weil es weniger tippen ist.

So wie Sprachdesigner, sollen sie sehen, dass eher die richtige Fehlerbehandlung mit noch geringerer Typisierung erfolgen. Ohne behauptet, weil Ihr Ausnahmemechanismus ausführlich ist nicht die Lösung. Oh, Moment mal, Go hat keine Ausnahmen entweder. Schade:)

Ich fühlte mich wie der Autor im Kopf zu treten, als ich das sah.

Ich verwende behauptet die ganze Zeit im Code und schließlich ersetzen sie alle, wenn ich mehr Code schreiben. Ich benutze sie, wenn ich nicht die Logik geschrieben haben, erforderlich und möchte benachrichtigt werden, wenn ich in den Code ausführen, anstatt eine Ausnahme zu schreiben, die gelöscht werden soll, da das Projekt näher Abschluss bekommt.

Ausnahmen mischen auch mit Produktionscode in leichter, die ich mag nicht. Eine Assertion ist einfacher als throw new Exception("Some generic msg or 'pretend i am an assert'"); zu bemerken

Mein Problem mit diesen Antworten assert zu verteidigen ist niemand legt deutlich, was sie von einem normalen unterscheiden fatal error , und warum eine Assertion nicht eine Teilmenge von einer Ausnahme sein . Jetzt, mit diesen Worten, was ist, wenn die Ausnahme nie erwischt? Ist, dass es eine Behauptung von Nomenklatur machen? Und warum sollte man sich nur wünschen, eine Beschränkung in der Sprache zu verhängen, die eine Ausnahme ausgelöst werden kann, dass / nichts / umgehen kann?

Ja, behauptet sind böse.

Oft werden sie dort eingesetzt, wo die richtige Fehlerbehandlung verwendet werden soll. Gewöhnen Sie sich von Anfang an Umgang mit richtigen Produktionsqualität Fehler zu schreiben!

In der Regel bekommen sie in der Art und Weise Unit-Tests zu schreiben (es sei denn, Sie eine benutzerdefinierte Assertion schreiben, die mit dem Test-Harnisch interagiert). Dies ist häufig, weil sie verwendet werden, wo die richtige Fehlerbehandlung verwendet werden soll.

Meistens sie aus Release zusammengestellt bekommen baut was bedeutet, dass keine ihrer „Test“ zur Verfügung, wenn Sie den Code ausführen, die Sie tatsächlich freigeben; in Multi-Threaded-Situationen die schlimmsten Probleme auftauchen oft nur in Freigabecode gegeben, dass diese schlecht sein kann.

Manchmal sind sie eine Krücke für sonst gebrochen Designs; das heißt, die Gestaltung des Codes ermöglicht es ein Benutzer es in einer Art und Weise zu nennen, dass es nicht und die Assertion aufgerufen werden soll „verhindert“ dies. Befestigen Sie den Entwurf!

ich darüber mehr auf meinem Blog im Jahr 2005 schrieb hier:

Wenn die behauptet, Sie sprechen bedeutet, dass das Programm erbricht und gibt dann können Behauptungen sehr schlecht sein. Dies ist nicht zu sagen, dass sie immer die falsche Sache zu verwenden, sie sind ein Konstrukt, das sehr leicht missbraucht wird. Sie haben auch viele bessere Alternativen. Solche Dinge sind gute Kandidaten für das Böse genannt zu werden.

Zum Beispiel, ein 3rd-Party-Modul (oder jedes Modul wirklich) soll so gut wie nie das aufrufende Programm verlassen. Dies gilt nicht gibt dem Aufruf Programmierer keine Kontrolle über das, was das Programm riskiert in diesem Moment nehmen soll. In vielen Fällen sind die Daten so wichtig, dass selbst beschädigte Daten zu speichern ist besser als die Daten zu verlieren. Behauptet kann Sie zwingen, Daten zu verlieren.

Einige Alternativen zu behauptet:

  • Mit einem Debugger,
  • Console / database / andere Anmeldung
  • Ausnahmen
  • Andere Arten von Fehlerbehandlung

Einige Referenzen:

Auch Menschen, die für assert befürworten denken, dass sie nur in der Entwicklung verwendet werden sollen und nicht in der Produktion:

Diese Person sagt, dass behauptet verwendet werden soll, wenn das Modul möglicherweise Daten beschädigt hat, dass eine Ausnahme bleibt nach geworfen wird: http://www.advogato.org/article/949.html . Dies ist sicherlich ein vernünftiger Punkt jedoch ein externes Modul sollte nie verschreiben, wie wichtig beschädigte Daten an das rufende Programm ist (durch „für“ sie verlässt). Der richtige Weg, dies zu umgehen ist durch das Auslösen einer Ausnahme, die es klar, dass das Programm macht jetzt in einem inkonsistenten Zustand sein kann. Und da gute Programme meist aus Modulen bestehen (mit einem wenig Klebstoff-Code im Hauptprogramm), behauptet, ist fast immer die falsche Sache zu tun.

Nicht so viel Böses wie allgemein kontraproduktiv. Es gibt eine Trennung zwischen permanenter Fehlerprüfung und Fehlersuche. Assert macht die Menschen denken alle Debuggen dauerhaft sein sollte und verursacht massive Lesbarkeit Probleme, wenn viel verwendet. Permanent Fehlerbehandlung sollte besser sein als das, wo nötig, und da assert ihre eigenen Fehler verursacht es ist eine ziemlich fragwürdige Praxis.

i verwenden assert nie () Beispiele zeigen in der Regel etwas wie folgt aus:

int* ptr = new int[10];
assert(ptr);

Das ist schlecht, ich dies nie tun, was ist, wenn mein Spiel ein paar Monster zuteilt? Warum soll ich das Spiel zum Absturz bringen, stattdessen sollten Sie die Fehler ordnungsgemäß handhaben, so etwas wie:

CMonster* ptrMonsters = new CMonster[10];
if(ptrMonsters == NULL) // or u could just write if(!ptrMonsters)
{
    // we failed allocating monsters. log the error e.g. "Failed spawning 10 monsters".
}
else
{
    // initialize monsters.
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top