代码之家  ›  专栏  ›  技术社区  ›  gour

Nimrod中类似Ada的类型

  •  10
  • gour  · 技术社区  · 12 年前

    今天,我确实在D邮件列表中询问了是否可以以类似于Ada的示例的方式定义和使用自定义数据类型 wiki 第页:

    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); 
    

    以及 reply 展示了如下内容:

    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;}());
    }
    

    这表明这是可能的,但可能错过了阿达的优雅。

    现在,在最近读到关于Nimrod的文章后,我想知道它如何在有规定的情况下处理类似的任务,以确保相同的Ada类型的安全?

    2 回复  |  直到 10 年前
        1
  •  7
  •   zah    12 年前

    Nimrod相当直接地支持这些:

    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]
    

    错误在编译时强制执行:

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

    ..或在运行时

    var x: Day
    var y = unknownInt() # let's say it returns 100
    
    x = y # unhandled exception: value 100 out of range [EOutOfRange]
    

    此外 distinct types 如果需要更强的类型安全性,则可以使用。

        2
  •  0
  •   Community CDub    8 年前

    此外,实例化变得更简单,使用

    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);
        }
    }
    

    看见 Instantiator Function for Bound template doesn't compile