Manchmal habe ich eine Funktion, die wahr oder falsch zurückgeben sollte. Aber manchmal wären drei mögliche Werte sinnvoller.
In einigen Sprachen werden diese Fälle mit ganzen Zahlen oder mit Ausnahmen behandelt.
Zum Beispiel möchten Sie das Alter eines Benutzers behandeln, wenn er über 18 Jahre alt ist. Und Sie haben eine Funktion wie diese.
if(user.isAdult(country_code)){
//Go On
}else{
// Block access or do nothing
}
Aber in einigen Fällen, abhängig davon, wie Ihre App erstellt wurde, kann es vorkommen, dass das Geburtstagsfeld unvollständig ist. Dann sollte diese Funktion etwas Unbestimmtes zurückgeben.
switch(user.isAdult()){
case true:
// go on
break;
case undetermined:
//Inform user birthday is incomplete
case false:
//Block access
}
Wie gesagt, wir können das mit Exceptions und Int umgehen, aber ich finde es ziemlich sexy, ein wahres, falsches, unbestimmtes eingebettetes Element in der Sprache zu haben, anstatt einige selbst definierte Konstanten zu verwenden.
Antworten:
Dies kann mit Aufzählungen, Ganzzahlen, Symbolen (z. B. Lisp, Ruby), nullfähigen Typen (verwenden Sie null als unbestimmten Zustand), Optionstypen (z. B. ML) oder einem ähnlichen Konstrukt behandelt werden - abhängig von Ihrer Sprache.
Obwohl Ihr Beispiel und Ihre Begründung stichhaltig sind, sehe ich nicht, dass es auf der Prioritätenliste der zu entwickelnden Sprachfunktionen steht.
quelle
null
. In C / C ++ können Sie eine Enumeration zurückgeben.Ich habe keinen Fall gesehen, in dem dies notwendig ist. Wenn dieses Feld in dem von Ihnen angegebenen Beispiel erforderlich ist, sollte es an einer anderen Stelle validiert worden sein.
isAdult()
ist von Natur aus eine Methode mit zwei Zuständen: Sie sind entweder oder Sie sind nicht. Es ist nicht erforderlich, dass es etwas anderes tut, als false zurückzugeben, wenn es auf Daten stößt, die es nicht verarbeiten kann. Zum Beispiel:quelle
.isAdult()
den Benutzer selbst abfragen, wenn Sie das wirklich wollen, und das würde besser funktionieren.wahr, falsch, unbekannt
ja Nein Vielleicht
In C # können Sie einen NULL-fähigen Bool verwenden (Sie können sich jetzt entsetzt zurückziehen).
In MS-SQL können Sie ein nullbares Bitfeld verwenden (dito)
quelle
unknown
.In C ++ kann dies mit einem Non-
bool
Return-Typ oder durch Auslösen einer Ausnahme behandelt werden. Wenn Sie einen Rückgabetyp mit drei Werten wünschen, verwenden Sie einenum
. Es ist nicht so sexy, aber es funktioniert, und was noch wichtiger ist, Sie können es tun, ohne die Sprache für den Rest von uns durcheinander zu bringen.Mit
bool
sei dreiwertigen Probleme verursachen würde. Wie gehen Sie vorbool foo; ... if (foo)...
, wenn Siefoo
einen der drei Werte annehmen ?bool
Variablen zu haben, die genau einer von ihnen sindfoo
und!foo
zu jeder Zeit wahr sind , hat Vorteile . Es hilft, über Programme nachzudenken.Überprüfen Sie, was Benutzer in der numerischen Verarbeitung tun, wenn sie möglicherweise
NaN
Werte erhalten. Es ist kompliziert. Ich möchte es lieber nicht für die normale boolesche Verarbeitung durchmachen müssen.Wenn Sie nicht
.isAdult()
genügend Informationen verarbeiten möchten , müssen Sie dies intern tun und dann entwedertrue
oder zurückgebenfalse
. Andernfalls müssen Sie jedes Mal, wenn Sie es verwenden, den Rückkehrcode überprüfen, bevor Sie etwas anderes tun, und eine Möglichkeit finden, damit umzugehen. Es würde bedeuten, dass Sie die Dokumente überprüfen müssten, um festzustellen, ob eine Funktion tatsächlich das getan hat, was der Name sagt, und das wäre eine Katastrophe für die Lesbarkeit.quelle
Die Idee ist sehr nützlich. Es gibt ein ganzes Feld, das dem Umgang mit Unsicherheit gewidmet ist und Fuzzy Logic heißt .
Zum Glück für uns Programmierer können Sie Fuzzy-Logik mit Standard-Sprachfunktionen implementieren.
In dem von Ihnen angegebenen Fall können die unsicheren Informationen zum Beispiel leicht ermittelt werden, indem Sie den Benutzer fragen. Eine Tristate-Aufzählung, wie Sie sie beschreiben, funktioniert also einwandfrei.
Es gibt viele andere Möglichkeiten, unsicher zu sein. Solche Fragen umfassen:
Viele dieser Fragen können mit Wahrscheinlichkeiten im Bereich von 0,0 (falsch) bis 1,0 (wahr) und Gleitkomma-Mathematik beantwortet werden.
Ein Computerchemiker und Informatiker namens David E. Shaw wandte so etwas an die Wall Street an und hat jetzt einen Wert von etwa 2,5 Milliarden US-Dollar. Also ja, es ist nützlich. :-)
quelle
Vor vielen Jahren habe ich mit einigen der Algorithmen gespielt, die herauskamen, um den Werten einen Glauben zuzuweisen. Hat Spaß gemacht. Letztendlich habe ich daraus gelernt, dass Boolesche Werte oft eine erfundene Passung sind. Eigentlich sollte es ein trileaner wahr / falsch / anderer Wert sein. Beim Experimentieren schien das zu der Zeit zu dem "besten" Code für mich zu führen. Ich bin seitdem zusammengebrochen und tue, was alle anderen tun, während ich intern überlegte, wie viel einfacher es sein KÖNNTE, wenn wir aufhören würden, Dinge auf die gleiche Weise wie früher zu tun ... :-)
quelle
Case- oder Switch-Anweisungen funktionieren jedoch einwandfrei, wenn Ganzzahlen verwendet werden, um willkürlich mit dem Switch umzugehen.
Wenn Sie in Ruby den Gleichheitsoperator verwenden, wird
nil == false
in einigen Fällen 'nil' als false zurückgegebenfalse
, sodass Sie Rubynil
für die Behandlung der ternären Logik verwenden können.quelle
Eine andere Möglichkeit in Ihrem Fall könnte darin bestehen, das Steuerelement durch Anwenden des "Tell Don't Ask" -Prinzips umzukehren und in zu ändern (entschuldigen Sie das Wort "Adultness", "Brain Blockade"):
wo
OnlyAllowAdultsToLoginStrategy
implementiert eine Schnittstelle:quelle
void userIsAdult()
das? Vielleicht meintest dubool userIsAdult()
?Mein Sohn fragte mich, wie ich vergleichbare Tests effizient durchführen könne. Die getesteten Flags waren nur wahr / falsch, aber die Matchkeys hatten drei Zustände (Es muss wahr sein, es muss falsch sein, oder es ist mir egal). Natürlich kann dies mit einer 2-Bit-Datenstruktur und ein wenig Twiddling implementiert werden, aber diese Art von Code muss wirklich kommentiert werden, da der Zweck nicht einfach zu erkennen ist, wenn man sich nur den Code ansieht.
quelle
C hat diese Funktion in den meisten Bibliotheksfunktionen implementiert. Beispiel: strcmp vergleicht 2 Zeichenfolgen und gibt 0 zurück, wenn sie gleich sind, 1 (dh eine positive ganze Zahl), wenn die erste größer als die zweite ist, und -1 (dh eine negative ganze Zahl), wenn die zweite größer als die erste ist .
Der gleiche Ansatz kann an anderer Stelle verwendet werden, + / 0 / - als Ihr Tri-State. Sie können damit auch boolesche Logik für die Werte ausführen, wenn Sie 0 kennen, wenn false und jeder andere Wert true ist.
quelle
Für C ++ implementiert Boost tatsächlich ein Tribool, das als solches beschrieben wird:
quelle
Das Kontrollkästchen VB6 bietet diese Funktion. Die Kontrollkästchenwerte können 0 = aus, 1 = ein, 2 = grau sein
quelle