2013-08-29 14 views
10

dzisiaj zapytałem na liście mailingowej D, czy można definiować i używać niestandardowych typów danych w sposób podobny do np. Przykład z Ady wiki strony:Typy Ada w Nimrod

type Day_type is range 1 .. 31; 
type Month_type is range 1 .. 12; 
type Year_type is range 1800 .. 2100; 
type Hours is mod 24; 
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); 


type Date is 
    record 
    Day : Day_type; 
    Month : Month_type; 
    Year : Year_type; 
    end record; 

subtype Working_Hours is Hours range 0 .. 12; 
subtype Working_Day is Weekday range Monday .. Friday; 
Work_Load: constant array(Working_Day) of Working_Hours 
    := (Friday => 6, Monday => 4, others => 10); 

i reply wykazały coś takiego:

import std.typecons; 
import std.exception; 

struct Limited(T, T lower, T upper) 
{ 
    T _t; 
    mixin Proxy!_t; //Limited acts as T (almost) 
    invariant() 
    { 
     enforce(_t >= lower && _t <= upper); 
    } 
    this(T t) 
    { 
     _t = t; 
    } 
} 

auto limited(T, T lower, T upper)(T init = T.init) 
{ 
    return Limited!(T, lower, upper)(init); 
} 

unittest 
{ 
    enum l = [-4,9]; 
    auto a = limited!(int, l[0], l[1])(); 
    foreach(i; l[0] .. l[1]+1) 
    { 
     a = i; 
    } 

    assertThrown({a = -5;}()); 
    assertThrown({a = 10;}()); 
} 

który pokazuje, że to możliwe, ale prawdopodobnie nie zdobywa elegancję Ady.

Teraz, po przeczytaniu ostatnio o Nimroda, zastanawiam się, jak poradzi sobie z podobnym zadaniem z zapewnieniem bezpieczeństwa tego samego Ada?

Odpowiedz

7

Nimroda wspierania co raczej bezpośrednio:

type 
    Day = range[1..31] 
    Month = range[1..12] 

    WeekDay = enum 
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday 

    WorkingDays = range[Monday..Friday] 
    WorkingHours = range[0..12] 

    WorkSchedule = array[WorkingDays, WorkingHours] 

Błędy są wykonywane albo w czasie kompilacji:

var x: Day 
x = 40 # conversion from int literal(40) to Day is invalid 

.. lub w okresie czasu

var x: Day 
var y = unknownInt() # let's say it returns 100 

x = y # unhandled exception: value 100 out of range [EOutOfRange] 

Ponadto distinct types może być użyty, jeśli wymagane jest jeszcze mocniejsze bezpieczeństwo.

+0

Dziękuję. Araq opublikował także na #ada, gdzie mieliśmy małą dyskusję. Nie wiedziałem, że Nimrod robi to tak elegancko jak Ady i jest z tego całkiem zadowolony, ale uważam, że brak powiązań GUI utrzyma mnie z Adą. – gour

+0

Cóż, Ada nie jest tak naprawdę znana ze swoich wiązań graficznych. (Chociaż natknąłem się na to (http://people.cs.kuleuven.be/~dirk/ada-why2.html), co oznacza, że ​​* są * niektóre dobre/łatwe w użyciu istniejące pakiety.) Ale , mam nadzieję, że będzie trochę pracy nad naprawianiem rzeczy i dobrem. otwarty, niezależny od platformy pakiet GUI będzie dostępny. (Nie uważam zwykłych wiązań za kwalifikacje.) – Shark8

0

Ponadto instancji staje się jednym argumentem prostsze przy użyciu

import std.traits; 

/*! Instantiator for \c Limited. */ 
template limited(alias min, alias max, bool Exceptional = true) 
    if (!is(CommonType!(typeof(min), typeof(max)) == void)) { 
    auto limited(CommonType!(typeof(min), typeof(max)) value) { 
     return Limited!(typeof(value), min, max)(value); 
    } 
} 

Zobacz Instantiator Function for Bound template doesn't compile