Viele Sprachen mögen C++
, C#
und Java
ermöglichen es Ihnen, Objekte zu erstellen, die einfache Typen wie integer
oder darstellen float
. Mit einer Klassenschnittstelle können Sie Operatoren überschreiben und logisch prüfen, ob ein Wert eine Geschäftsregel von 100 überschreitet.
Ich frage mich, ob es in einigen Sprachen möglich ist, diese Regeln als Anmerkungen oder Attribute einer Variablen / Eigenschaft zu definieren.
Zum Beispiel C#
könnten Sie schreiben:
[Range(0,100)]
public int Price { get; set; }
Oder vielleicht C++
könnten Sie schreiben:
int(0,100) x = 0;
Ich habe so etwas noch nie gesehen, aber angesichts der Tatsache, wie abhängig wir von der Datenvalidierung vor der Speicherung geworden sind. Es ist seltsam, dass diese Funktion nicht zu Sprachen hinzugefügt wurde.
Können Sie Beispiele für Sprachen nennen, in denen dies möglich ist?
quelle
data Bool = True | False
und für das, was Sie wollen , könnte man sagen ,data Cents = 0 | 1 | 2 | ...
eine haben Blick auf „Algebraische Datentypen“ (was mehr richtig mit Typinferenz benannt werden sollte hindley-milner Typen , aber die Leute zu verwirren , dass annoyingly) en.wikipedia.org/wiki/Algebraic_data_typetype
Schließlich gibt es in Pascal ein Schlüsselwort. Objektorientierung ist eher ein Entwurfsmuster als eine "atomare" Eigenschaft von Programmiersprachen.Antworten:
Pascal hatte Unterbereichstypen, dh die Anzahl der Zahlen, die in eine Variable passen, wurde verringert.
Ada hat auch eine Vorstellung von Bereichen: http://en.wikibooks.org/wiki/Ada_Programming/Types/range
Aus Wikipedia ....
kann auch tun
Und hier wird es cool
C hat keinen strengen Unterbereichstyp, aber es gibt Möglichkeiten, einen (zumindest eingeschränkten) nachzubilden, indem Bitfelder verwendet werden, um die Anzahl der verwendeten Bits zu minimieren.
struct {int a : 10;} my_subrange_var;}
. Dies kann als Obergrenze für variablen Inhalt dienen (im Allgemeinen würde ich sagen: Verwenden Sie keine Bitfelder , dies ist nur ein Beweis für einen Punkt).Viele Lösungen für Integer-Typen beliebiger Länge in anderen Sprachen finden eher auf Bibliotheksebene statt, dh C ++ ermöglicht vorlagenbasierte Lösungen.
Es gibt Sprachen, mit denen variable Zustände überwacht und Zusicherungen damit verbunden werden können. Zum Beispiel in Clojurescript
Die Funktion
mytest
wird aufgerufen, wenna
sich (überreset!
oderswap!
) geändert hat und überprüft, ob die Bedingungen erfüllt sind. Dies könnte ein Beispiel für die Implementierung des Verhaltens von Unterbereichen in Sprachen mit später Bindung sein (siehe http://blog.fogus.me/2011/09/23/clojurescript-watchers-and-validators/ ).quelle
for y in Year_Type loop ...
wodurch Probleme wie Pufferüberläufe beseitigt werden.Ada ist auch eine Sprache, die Grenzen für einfache Typen zulässt. In Ada empfiehlt es sich , eigene Typen für Ihr Programm zu definieren, um die Korrektheit zu gewährleisten.
Es wurde lange Zeit vom Verteidigungsministerium verwendet, ist es vielleicht immer noch, aber ich habe den Überblick über seine derzeitige Verwendung verloren.
quelle
Siehe Einschränken des Wertebereichs in C ++ Beispiele zum Erstellen eines Bereichsüberprüfung in C ++.
Zusammenfassung: Verwenden Sie eine Vorlage, um einen Wertetyp mit integrierten Mindest- und Höchstwerten zu erstellen, die Sie folgendermaßen verwenden können:
Sie brauchen hier nicht einmal eine Vorlage. Sie könnten eine Klasse mit ähnlichem Effekt verwenden. Mithilfe einer Vorlage können Sie den zugrunde liegenden Typ angeben. Es ist auch wichtig zu beachten, dass der oben genannte Typ
percent
keinfloat
, sondern eine Instanz der Vorlage ist. Dies entspricht möglicherweise nicht dem Aspekt "einfache Typen" Ihrer Frage.Einfache Typen sind genau das - einfach. Sie werden häufig am besten als Bausteine für die Erstellung der benötigten Tools verwendet, anstatt direkt verwendet zu werden.
quelle
Eine eingeschränkte Form Ihrer Absicht ist meines Wissens nach in Java und C # durch eine Kombination aus Anmerkungen und dynamischem Proxy-Muster möglich (es gibt integrierte Implementierungen für dynamische Proxys in Java und C #).
Java-Version
Die Anmerkung:
Die Wrapper-Klasse, die die Proxy-Instanz erstellt:
Der InvocationHandler, der bei jedem Methodenaufruf als Bypass dient:
Die Beispiel-Oberfläche zur Verwendung:
Hauptmethode:
Ausgabe:
C # -Version
Die Anmerkung (in C # Attribut genannt):
Die DynamicObject-Unterklasse:
Die ExampleClass:
Verwendung:
Abschließend sehen Sie, dass Sie so etwas in Java zum Laufen bringen können , aber es ist nicht ganz praktisch, weil
Die Funktionen der DynamicObject-Klasse in C # heben die Schnittstelleneinschränkung auf, wie Sie in der C # -Implementierung sehen. Leider wird durch dieses dynamische Verhalten die Sicherheit statischer Typen in diesem Fall aufgehoben. Daher sind Laufzeitprüfungen erforderlich, um festzustellen, ob ein Methodenaufruf für den dynamischen Proxy zulässig ist.
Wenn diese Einschränkungen für Sie akzeptabel sind, kann dies als Grundlage für das weitere Graben dienen!
quelle
public virtual int Min { get; private set; }
IhrerBereiche sind ein Sonderfall von Invarianten. Aus Wikipedia:
Ein Bereich
[a, b]
kann als Variable x vom TypInteger
mit den Invarianten x> = a und x <= b deklariert werden .Daher sind Ada- oder Pascal-Unterbereichstypen nicht unbedingt erforderlich. Sie könnten mit einem Integer-Typ mit Invarianten implementiert werden.
quelle
In C ++ und anderen Sprachen mit leistungsstarken Typsystemen sind keine speziellen Funktionen für Typen mit eingeschränktem Bereich erforderlich.
In C ++ können Ihre Ziele mit benutzerdefinierten Typen relativ einfach erreicht werden . Und in Anwendungen, in denen Typen mit begrenzter Reichweite wünschenswert sind, reichen sie kaum aus . Beispielsweise möchte man auch, dass der Compiler überprüft, ob physikalische Einheitenberechnungen korrekt geschrieben wurden, sodass Geschwindigkeit / Zeit eine Beschleunigung erzeugt und die Quadratwurzel aus Beschleunigung / Zeit eine Geschwindigkeit erzeugt. Dies erfordert die Möglichkeit, ein Typensystem zu definieren, ohne jeden Typ, der jemals in einer Formel vorkommen könnte, explizit zu benennen. Dies kann in C ++ erfolgen .
quelle